rss feed into custom browser activity instead of normal browser - android

So I have my browser activity ready, however I'm struggling to get the code working to open the link from my rss feed to open in that, it just goes to a blank page. I have tried numerous things but nothing is working. So I have ended up going back to standard code as used in this tutorial http://www.itcuties.com/android/how-to-write-android-rss-parser/ . I am using the engadget feed as an example to see if i could get it working. Here is my listlistener activity
public class ListListener implements OnItemClickListener {
// List item's reference
List<RssItem> listItems;
// Calling activity reference
Activity activity;
public ListListener(List<RssItem> aListItems, Activity anActivity) {
listItems = aListItems;
activity = anActivity;
}
/**
* Start a browser with url from the rss item.
*/
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(listItems.get(pos).getLink()));
activity.startActivity(i);
}
}
and here is my engadgetfeed activity
public class EngadgetFeed extends Activity {
private EngadgetFeed local;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_engadget_feed);
// Set reference to this activity
local = this;
GetRSSDataTask task = new GetRSSDataTask();
// Start download RSS task
task.execute("http://www.engadget.com/rss.xml");
// Debug the thread name
Log.d("Engadget", Thread.currentThread().getName());
}
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
#Override
protected List<RssItem> doInBackground(String... urls) {
// Debug the task thread name
Log.d("Engadget", Thread.currentThread().getName());
try {
// Create RSS reader
RssReader rssReader = new RssReader(urls[0]);
// Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("Engadget", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(List<RssItem> result) {
// Get a ListView from main view
ListView endgadgetfeed = (ListView) findViewById(R.id.listMainView);
// Create a list adapter
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem> (local,R.layout.simple_list_item_1, result);
// Set list adapter for the ListView
endgadgetfeed.setAdapter(adapter);
// Set list view item click listener
endgadgetfeed.setOnItemClickListener(new ListListener(result, local));
}
}
}
any help would be appreciated

Well what I had to do, and i'm over the moon for answering my own question, is the following;
instead of having the following:
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(listItems.get(pos).getLink()));
activity.startActivity(i);
}
I used this:
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
Uri uri;
String stringuri;
stringuri = (Uri.parse(listItems.get(pos).getLink())).toString();
Intent i = new Intent(activity, Browser2.class);
i.putExtra(EXTRA_MESSAGE, stringuri);
activity.startActivity(i);
}
So I hope this helps others who have the same.

Related

How to download entire S3 bucket automatically

I am able to successfully download all files from aws s3 bucket, so when I click on the particular list item the list item gets download. But, I want all s3 bucket item automatically download when activity is launched.
/**
* DownloadSelectionActivity displays a list of files in the bucket. Users can
* select a file to download.
*/
public class DownloadSelectionActivity extends ListActivity {
// The S3 client used for getting the list of objects in the bucket
private AmazonS3Client s3;
// An adapter to show the objects
private SimpleAdapter simpleAdapter;
private ArrayList<HashMap<String, Object>> transferRecordMaps;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download_selection);
initData();
initUI();
}
#Override
protected void onResume() {
super.onResume();
// Refresh the file list.
new GetFileListTask().execute();
}
private void initData() {
// Gets the default S3 client.
s3 = Util.getS3Client(DownloadSelectionActivity.this);
transferRecordMaps = new ArrayList<HashMap<String, Object>>();
}
private void initUI() {
simpleAdapter = new SimpleAdapter(this, transferRecordMaps,
R.layout.bucket_item, new String[] {
"key"
},
new int[] {
R.id.key
});
simpleAdapter.setViewBinder(new ViewBinder() {
#Override
public boolean setViewValue(View view, Object data,
String textRepresentation) {
switch (view.getId()) {
case R.id.key:
TextView fileName = (TextView) view;
fileName.setText((String) data);
return true;
}
return false;
}
});
// When an item is selected, finish the activity and pass back the S3
// key associated with the object selected
getListView().setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(final AdapterView<?> adapterView, View view, int pos, long id) {
Intent intent = new Intent();
intent.putExtra("key", (String) transferRecordMaps.get(pos).get("key"));
setResult(RESULT_OK, intent);
finish();
}
});
}
/**
* This async task queries S3 for all files in the given bucket so that they
* can be displayed on the screen
*/
private class GetFileListTask extends AsyncTask<Void, Void, Void> {
// The list of objects we find in the S3 bucket
private List<S3ObjectSummary> s3ObjList;
// A dialog to let the user know we are retrieving the files
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(DownloadSelectionActivity.this,
getString(R.string.refreshing),
getString(R.string.please_wait));
}
#Override
protected Void doInBackground(Void... inputs) {
// Queries files in the bucket from S3.
s3ObjList = s3.listObjects(Constants.BUCKET_NAME).getObjectSummaries();
transferRecordMaps.clear();
for (S3ObjectSummary summary : s3ObjList) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("key", summary.getKey());
transferRecordMaps.add(map);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
dialog.dismiss();
simpleAdapter.notifyDataSetChanged();
}
}
}
You already have the list of objects in the bucket, you could just iterate through the list and download each one when the list operation has completed. It might be easier to handle the transfers (allowing pause/resume, checking status, ect...) using the Transfer Utility, which is a high level utility on top of the standard S3 Client.
A guide for the Transfer Utility can be found here (http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/s3transferutility.html)

How to use notifyDataSetChanged with finish()

I have a list view which show list of task, on selecting task it shows details about task, when I delete the particular task it returns to the previous activity by finish(). but it does not update the list.
I want to know how and where to use notifyDataSetChanged method and add adapter method is never used.
Other than notifyDataSetChanged() solution is also accepted :) i just want to update the list when it returns to the previous activity.
Do it with startActivityForResult(). When you create intent to open new activity open it for result. The task being deleted is your result. So when it's marked as deleted and you return to your previous activity, the result triggers and you can delete the marked item + call the notify.
More info here : http://developer.android.com/training/basics/intents/result.html
you can use the notifyDataSetChanged on the onResume method, this always update the data itself when the Activity shows
You can also notify your parent activity before finishing your current activity. You just have to register a Receiver in your main activity and all others activities will be able to notify that activity. You can even send data!
As my english is not that good, sample code :
The MainActivity class
public class MainActivity extends AppCompatActivity {
// you can define your name for your receiver as a constant,
// so you can access it from other activities if you want
public static final String MY_SUPER_INTERNAL_NOTIFICATION = "MY_SUPER_INTERNAL_NOTIFICATION";
public static final String MY_OBJECT = "my_object";
public static final String MY_OBJECT_POSITION = "my_object_position" ;
private MyCustomAdapter adapter;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
// set up your list with your adapter and data...
adapter = new MyCustomAdapter(this);
// [...] I suppose you know how to do that, I dont write everything
listView.setAdapter(adapter);
// when you click on a row from your list,
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(
MainActivity.this,
SecondActivity.class
);
// you can for example put data in a Bundle and pass it to the other activity
// then on the onCreate you can use that data as you want
Bundle bundle = new Bundle();
// IMPORTANT be sure that the object you are putting in the bundle is Serializable (implements Serializable)
bundle.putSerializable(MY_OBJECT, adapter.getItem(position));
// you can also for example send the position of the row you clicked
bundle.putInt(MY_OBJECT_POSITION, position);
// put your bundle in the intent
intent.putExtras(bundle);
startActivity(intent);
}
});
// register your Receiver! don't forget to do that or you will never be notified
LocalBroadcastManager
.getInstance(this)
.registerReceiver(
broadcastReceiver,
new IntentFilter(MY_SUPER_INTERNAL_NOTIFICATION)
);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
// get the position sent by the other activity
int position = intent
.getExtras()
.getInt(SecondActivity.MY_EXAMPLE_KEY);
adapter.deleteItem(position);
}
}
};
// adapter class...
private class MyCustomAdapter extends BaseAdapter {
ArrayList<MyObject> data;
public MyCustomAdapter(Context context) {
}
public void deleteItem(int position){
// delete your item from the list of data
data.remove(position);
// dont forget to notify
notifyDataSetChanged();
}
#Override
public int getCount() {
return 0;
}
#Override
public MyObject getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
// adapter class, you can extend your favorite type of adapter
}
}
The SecondActivity class :
public class SecondActivity extends AppCompatActivity {
public static final String MY_EXAMPLE_KEY = "EXAMPLE";
private MyObject myObject;
private int myObjectPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
myObject = (MyObject) getIntent()
.getExtras()
.getSerializable(MainActivity.MY_OBJECT);
myObjectPosition = getIntent()
.getExtras()
.getInt(MainActivity.MY_OBJECT_POSITION);
// do all your stuff with your object
// before calling finish do this
beforeFinishDoThisStuff();
}
private void beforeFinishDoThisStuff() {
sendBroadcastToMainActivity();
finish();
}
private void sendBroadcastToMainActivity() {
// create an intent and put your Receiver name as action name
// like you defined in your MainActivity
Intent intent = new Intent(MainActivity.MY_SUPER_INTERNAL_NOTIFICATION);
Bundle bundle = new Bundle();
// put whatever you want, here I put just the previous position of the object in the list
bundle.putInt(MY_EXAMPLE_KEY, myObjectPosition);
intent.putExtras(bundle);
// notify your MainActivity
LocalBroadcastManager
.getInstance(this)
.sendBroadcast(intent);
// after this finish !
}
}
Hope you understand how to notify activities with BroadcastManager. It's very powerful and simple to use.
Have fun coding !

Asynctask from Asynctask

My app requires to parse a XML file when the activity is launched. So, I use an Asynctask to parse the XML.
After parsing the XML file, I get the count of number of test-cases in the XML in doInBackground() method, and I use the variable alTestCaseList to keep this count.
Later in onPostExecute() method, I set the ArrayAdapter and register the click listener for the list.
However, when I click any testcase from the list, I'm supposed to parse the test-case entries from the XML again.
So I believe for this I'll have to use an AsyncTask again. So do I start another AsyncTask for onPostExecute() method of first AsyncTask?
Is there any other neat way of doing this?
I tried to put setOnItemClickListener() in onCreate() method, but it resulted in fatal exception with the message: "setOnItemClickListener(android.widget.AdapterView$OnItemClickListener) on a null object reference"........
Kindly give your suggestion.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testcases);
xmlHelp = new XmlHelper();
ConfigParser confParser = new ConfigParser();
confParser.execute();
}
private class ConfigParser extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
alTestCaseList = xmlHelp.getNumberOfNodes();
return null;
}
#Override
protected void onPostExecute(Void v) {
testCasesListView = (ListView) findViewById(R.id.lstTestCases);
arrayAdapter = new ArrayAdapter(TestCasesActivity.this, android.R.layout.simple_list_item_1, alTestCaseList);
testCasesListView.setAdapter(arrayAdapter);
testCasesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
String value = (String) adapter.getItemAtPosition(position);
Log.d("QcTool", "Selected: " + value);
}
});
}
}
Here is my take on the solution. Pass your data as an argument to the task and notify the adapter when you get the list.
See the comments for further explanation. Note that this approach does not handle issues that AsyncTask's typically come with is situations such as configuration changes.
You can then create another ParseXmlTask class which can be called in your OnItemClicked method
private ListView testCasesListView;
private ArrayAdapter arrayAdapter;
private List<String> testCasesList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testcases);
//Init the list - it's empty but your task will fill it.
testCasesList = new ArrayList<>();
//Init your listView
testCasesListView = (ListView) findViewById(R.id.lstTestCases);
//Add adapter to the listView
arrayAdapter = new ArrayAdapter(TestCasesActivity.this, android.R.layout.simple_list_item_1, alTestCaseList);
//Add your click event
testCasesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
//When clicked, do something awesome
String value = (String) adapter.getItemAtPosition(position);
Log.d("QcTool", "Selected: " + value);
//Create and start parseXmlTask here
}
});
xmlHelp = new XmlHelper();
//Pass in your callback as an argument
ConfigParserTask confParser = new ConfigParserTask(new OnConfigParserTaskCompleted(){
public void onConfigParserTaskCompleted(List<String> result){
//Simply refresh the list
testCasesList.clear();
testCasesList.addAll(result);
//Let the adapter know that the list has changed
//Then update the list view
arrayAdapter.notifyDataSetChanged();
}
});
confParser.execute(xmlHelp);
}
//It's better to pass in the info to the task as arguments than it is to rely on
//field variables
private class ConfigParserTask extends AsyncTask<XmlHelper, Void, List<String>> {
private OnConfigParserTaskCompleted listener;
public ConfigParser(OnConfigParserTaskCompleted listener){
this.listener = listener;
}
#Override
protected Void doInBackground(XmlHelper... params) {
//Do what you need to in the background
//Get your nodes then return it here
List<String> nodes = params[0].getNumberOfNodes();
return nodes;
}
#Override
protected void onPostExecute(List<String> result) {
//pass the result to the callback
listener.onConfigParserTaskCompleted(result);
}
}
//Callback to let your activity/fragment know when
//the task is complete
public interface OnConfigParserTaskCompleted{
public void onConfigParserTaskCompleted(List<String> result);
}
You can do something like this using AsyncTasks
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testcases);
testCasesListView = (ListView) findViewById(R.id.lstTestCases);
testCasesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
String value = (String) adapter.getItemAtPosition(position);
Log.d("QcTool", "Selected: " + value);
ParserNodeTask nodeTask = new ParserNodeTask();
nodeTask.execute(value);
}
});
xmlHelp = new XmlHelper();
ParserNumberOfNodesTask numberOfNodesTask = new ParserNumberOfNodesTask();
numberOfNodesTask.execute();
}
private class ParserNumberOfNodesTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
alTestCaseList = xmlHelp.getNumberOfNodes();
return null;
}
#Override
protected void onPostExecute(Void v) {
arrayAdapter = new ArrayAdapter(TestCasesActivity.this, android.R.layout.simple_list_item_1, alTestCaseList);
testCasesListView.setAdapter(arrayAdapter);
}
}
private class ParserNodeTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(String... params) {
String value = params[0];
//TODO : parse the selected node
}
#Override
protected void onPostExecute(Void v) {
//TODO: dunno what you need to do later
}
}
Though AsyncTasks are not ideal for this for many reasons (but easier to implement). You should maybe take a look on to Loaders or Services (i.e https://stackoverflow.com/a/6957909/665823)

What is the error in this android code that the app crashes? [duplicate]

This question already has answers here:
Can't create handler inside thread that has not called Looper.prepare()
(30 answers)
Closed 8 years ago.
This is my code. When I click on my app logo, after the splash screen, this is the class that is first called from an intent. But, after the tab is loaded, and onPreExecute() is once executed, the app crashes.
public class HomeActivity extends Activity{
private static final String dialog = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_main_tab_home);
new HomeDownloadPage().execute();
}
public class HomeDownloadPage extends AsyncTask<String,Void,String>{
private final ProgressDialog dialog = new ProgressDialog(HomeActivity.this);
protected void onPreExecute() {
this.dialog.setMessage("Have Paitence! ");
this.dialog.show();
}
#Override
protected String doInBackground(String... params) {
User user = null;
try {
user = new User("4eeb");
user.getList();
/*
* Custom adapter
* */
ArrayList<User> users = new ArrayList<User>();
for(User u : user.following){
users.add(u);
}
ListView lv = (ListView) findViewById(R.id.user_list);
final UserFollowingListAdapter csl = new UserFollowingListAdapter(HomeActivity.this,R.layout.user_list,users,this);
OnItemClickListener listener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
Object o = csl.getItem(position);
setTitle(parent.getItemAtPosition(position).toString());
}
};
lv.setAdapter(csl);
lv.setOnItemClickListener(listener);
/*
* Onclick listener
* */
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Intent i = new Intent("com.list.SEARCH");
Toast.makeText(HomeActivity.this, "rowitem clicked", Toast.LENGTH_LONG).show();
// TODO Auto-generated method stub
}
});
} catch (Exception e) {
showError();
}
return null;
}
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
}
}
public void showError(){
new AlertDialog.Builder(HomeActivity.this)
.setTitle(" Oops , Server down :( ")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
//
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Do nothing.
}
}).show();
}
}
Error I get is at the doInBackground() function.
Exact error: 01-19 19:03:01.264: E/AndroidRuntime(1138): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
What is the problem?
You are attempting to do things involving the UI (ListView lv = (ListView) findViewById(R.id.user_list);) within a background thread. You can not do this. You may process information in the background, then pass it back to the UI thread and update the UI
As pyrodante said, you're attempting to modify the UI while not on the UI thread. If you want modify the UI from a non-UI thread, you can use the runOnUiThread() function. That said, there's a better solution to your problem. You really should be using a Loader. They were basically designed to address exactly what you're trying to do. Note that even if you're designing an app that's pre-3.0, you can still access loaders via the Android Support package.

How Can I Update the activity(ListView) - android

I am using services and broadcast receiver, to launch a listview (I am using only two activity classes first as first class starts it starts service with it..in the services hitting a webservice and parsing data, n passing data into the broadcast receiver,
now the data I am getting in onreceive, and storing that data into another data...now I want this data to access in my activity class which I wl use for listView...please tell how can I do it..without making that var. static.
I also tried this thing within another way please if it is possible in that way too.
There the first screen is getting launch there I kept one button as I click on the button service will start n will do the whole job as I wrote above.....but here as I click the button another activity is being launched which is that listview but that isn't extending listActivity that is extending activity.
so I want to update that list view dynamically how can I do this?
please, any Help is Appreciable.
my code is here where I am getting stuck
public class MessageList extends Activity {
public static final String TAG = MessageList.class.getSimpleName();
Context mContext;
public static ArrayList<String> mData;
public ListView mListView;
private List<Message> messages;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.maina);
System.out.println("check bro"+mData);
System.out.println("In OnCreate of Messagelist class");
System.out.println("1st");
System.out.println("3rd");
mListView = (ListView) findViewById(R.id.mylist);
PlaceAdapter adapter = new PlaceAdapter(this, mData);
mListView.setAdapter(adapter);
}
private OnItemClickListener mItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(android.widget.AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent viewMessage = new Intent(Intent.ACTION_VIEW,Uri.parse(messages.get(arg2).getLink().toExternalForm()));
startActivity(viewMessage);
}
};
/* #Override
protected void onListItemClick(ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
Intent viewMessage = new Intent(Intent.ACTION_VIEW, Uri.parse(messages
.get(position).getLink().toExternalForm()));
this.startActivity(viewMessage);
}*/
class MessageListBroadCast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("hello");
System.out.println("final Done");
Bundle bundle = intent.getExtras();
mData = bundle.getStringArrayList("keya");
Log.d(TAG, "" + mData);
intent.putExtra("name", mData);
}
};
}
that message list is the class which is a list view
Thanks
Rather than working like this, I would use a class derived from CursorAdapter as Adapter and let your service store its results in a ContentProvider and notify changes on your ContentResolver on the same Uri you are using in the CursorAdapter. That way it will refresh automatically and your data is not lost should anything happen with your app (crash, memory,...). But I reckon this might be a bit of overhead, it all depends on what your webservice exactly does etc.

Categories

Resources