I have a very big problem guys. I have an app which fetches and parses the RSS feed from a blog, but I don't know how to put the results into my widget.
Here is the RSSListActivity which shows the rss feed correctly in it's own activity:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
RSSItem data = itemlist.get(position);
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(data.link));
startActivity(intent);
}
private void retrieveRSSFeed(String urlToRssFeed,ArrayList<RSSItem> list)
{
try
{
URL url = new URL(urlToRssFeed);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
RSSParser theRssHandler = new RSSParser(list);
xmlreader.setContentHandler(theRssHandler);
InputSource is = new InputSource(url.openStream());
xmlreader.parse(is);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private class RetrieveRSSFeeds extends AsyncTask<Void, Void, Void>
{
private ProgressDialog progress = null;
#Override
protected Void doInBackground(Void... params) {
retrieveRSSFeed("http://blog.qubiz.com/index.php/feed",itemlist);
rssadaptor = new RSSListAdaptor(RSSListActivity.this, R.layout.rssitemview,itemlist);
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
}
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(
RSSListActivity.this, null, "Loading RSS Feed... Please wait");
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
setListAdapter(rssadaptor);
progress.dismiss();
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
private class RSSListAdaptor extends ArrayAdapter<RSSItem>{
private List<RSSItem> objects = null;
public RSSListAdaptor(Context context, int textviewid, List<RSSItem> objects) {
super(context, textviewid, objects);
this.objects = objects;
}
#Override
public int getCount() {
return ((null != objects) ? objects.size() : 0);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public RSSItem getItem(int position) {
return ((null != objects) ? objects.get(position) : null);
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(null == view)
{
LayoutInflater vi = (LayoutInflater)RSSListActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.rssitemview, null);
}
RSSItem data = objects.get(position);
if(null != data)
{
TextView title = (TextView)view.findViewById(R.id.txtTitle);
TextView date = (TextView)view.findViewById(R.id.txtDate);
TextView description = (TextView)view.findViewById(R.id.txtDescription);
title.setText(data.title);
date.setText("on " + data.date);
String prova = android.text.Html.fromHtml(data.description).toString();
//description.setText(data.description);
description.setText(prova);
}
return view;
}
}
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(1,1,0,"About");
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case 1:
AlertDialog.Builder conferma_canc = new AlertDialog.Builder(this);
conferma_canc.setTitle("About");
conferma_canc.setMessage("Copyright © 2012 Qubiz. All rights reserved. Android version designed and developed by Csosz Gergo Levente, Qubiz Romania.");
conferma_canc.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = conferma_canc.create();
alert.show();
return true;
}
return false;
}
And here it is my RSS parser which also works as it should:
public class RSSParser extends DefaultHandler {
private final static String TAG_ITEM = "item";
private final static String[] xmltags = { "title", "link", "pubDate", "description" };
private RSSItem currentitem = null;
private ArrayList<RSSItem> itemarray = null;
private int currentindex = -1;
private boolean isParsing = false;
private StringBuilder builder = new StringBuilder();
public RSSParser(ArrayList<RSSItem> itemarray) {
super();
this.itemarray = itemarray;
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
if(isParsing && -1 != currentindex && null != builder)
{
builder.append(ch,start,length);
}
}
#Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if(localName.equalsIgnoreCase(TAG_ITEM))
{
currentitem = new RSSItem();
currentindex = -1;
isParsing = true;
itemarray.add(currentitem);
}
else
{
currentindex = itemIndexFromString(localName);
builder = null;
if(-1 != currentindex)
builder = new StringBuilder();
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if(localName.equalsIgnoreCase(TAG_ITEM))
{
isParsing = false;
}
else if(currentindex != -1)
{
if(isParsing)
{
switch(currentindex)
{
case 0: currentitem.title = builder.toString(); break;
case 1: currentitem.link = builder.toString(); break;
case 2: currentitem.date = builder.toString(); break;
case 3: currentitem.description= builder.toString(); break;
}
}
}
}
private int itemIndexFromString(String tagname){
int itemindex = -1;
for(int index= 0; index<xmltags.length; ++index)
{
if(tagname.equalsIgnoreCase(xmltags[index]))
{
itemindex = index;
break;
}
}
return itemindex;
}
}
My ExampleAppWidgetProvider.java where is a sample clock widget code which I want to replace to show my rss feed.
public class ExampleAppWidgetProvider extends AppWidgetProvider {
static DateFormat df = new SimpleDateFormat("hh:mm:ss");
private static final String LOG_TAG = "ExampleWidget";
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
Log.i("ExampleWidget", "Updating widgets " + Arrays.asList(appWidgetIds));
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, ExampleAppWidgetProvider.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget1);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
views.setTextViewText(R.id.widget1label, df.format(new Date()));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
private PendingIntent createClockTickIntent(Context context) {
Intent intent = new Intent(CLOCK_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.d(LOG_TAG, "Widget Provider enabled. Starting timer to update widget every second");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),1000, createClockTickIntent(context));
}
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.d(LOG_TAG, "Widget Provider disabled. Turning off timer");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createClockTickIntent(context));
}
public static String CLOCK_WIDGET_UPDATE = "com.eightbitcloud.example.widget.8BITCLOCK_WIDGET_UPDATE";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.d(LOG_TAG, "Received intent " + intent);
if (CLOCK_WIDGET_UPDATE.equals(intent.getAction())) {
Log.d(LOG_TAG, "Clock update");
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for (int appWidgetID : ids) {updateAppWidget(context, appWidgetManager, appWidgetID);
}
}
}
public static void updateAppWidget(Context context,AppWidgetManager appWidgetManager, int appWidgetId) {
String currentTime = df.format(new Date());
RemoteViews updateViews = new RemoteViews(context.getPackageName(),R.layout.widget1);
updateViews.setTextViewText(R.id.widget1label, currentTime);
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
}
}
Could any1 provide me a solution?
My aim is to: replace the widget's clock java code with my rss feed reader.
So I want to show the last rss item in the widget which is parsed by the rss parser. How can I do that?
Please provide code too, not only a few ideas, I am kinda new to android development.
Thank you for help in advance!
(Assuming you got RSS retrieval and parsing correctly)
You just have to change some text in widget:
AppWidgetManager manager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.name_of_your_widget_layout);
// set text of some view
views.setTextViewText(R.id.widget_amount_cameras, amountCameras);
// and of another view
views.setTextViewText(R.id.widget_location, locationCity);
// ... and yet another view
views.setTextViewText(R.id.locationStatus, locationStatus);
// get IDs of widgets , there could be more than one
final int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(YOurWidgetProviderClass.class.getPackage().getName(), YOurWidgetProviderClass.class.getName()));
// update all hte instances
manager.updateAppWidget(appWidgetIds, views);
You can change only some attributes of your widgets ( due to security constraints ) - See Javadoc of RemoteViews for further explanations
Related
With my app I send a message and a notification from my smartphone (called PHONE1) to another (called PHONE2). The message is received by PHONE2. PHONE2 send a reply message to PHONE1. PHONE1 receive a notification and read the message. PHONE1 send a reply message to PHONE2 and app crashes.
Messages.java:
public class Messages extends AppCompatActivity {
private static final String TAG = "ChatActivity";
Context context;
private ChatArrayAdapter chatArrayAdapter;
private ListView listView;
private EditText chatText;
private Button buttonSend;
private boolean side = false;
String from, to, mess;
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messages);
buttonSend = (Button) findViewById(R.id.send);
listView = (ListView) findViewById(R.id.chatMessage);
chatArrayAdapter = new ChatArrayAdapter(getApplicationContext(), R.layout.row_messages_right);
listView.setAdapter(chatArrayAdapter);
chatText = (EditText) findViewById(R.id.msg);
chatText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
return sendChatMessage();
}
return false;
}
});
buttonSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
sendChatMessage();
}
});
listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
listView.setAdapter(chatArrayAdapter);
//to scroll the list view to bottom on data change
chatArrayAdapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
listView.setSelection(chatArrayAdapter.getCount() - 1);
}
});
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
receiveChatMessage();
}
}, 0, 1000);
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
private boolean receiveChatMessage(){
InternalDatabaseOperations DB = new InternalDatabaseOperations(this);
Cursor CR = DB.getInformation(DB);
CR.moveToLast();
from = CR.getString(0);
to = CR.getString(1);
if(!Objects.equals(mess, CR.getString(2))){
mess = CR.getString(2);
chatArrayAdapter.add(new ChatMessage(!side, mess));
return true;
}
return false;
}
//Send chat message
private boolean sendChatMessage() {
mess = chatText.getText().toString();
chatArrayAdapter.add(new ChatMessage(side,mess));
chatText.setText("");
InternalDatabaseOperations DB = new InternalDatabaseOperations(this);
Cursor CR = DB.getInformation(DB);
CR.moveToLast();
from = CR.getString(1);
to = CR.getString(0);
BackgroundTaskSendingMessage sendingMessage = new BackgroundTaskSendingMessage(this);
sendingMessage.execute(to, from, mess);
return true;
} }
chatArrayAdapter.java:
class ChatArrayAdapter extends ArrayAdapter<ChatMessage> {
private TextView chatText;
private List<ChatMessage> chatMessageList = new ArrayList<>();
private Context context;
#Override
public void add(ChatMessage object) {
chatMessageList.add(object);
super.add(object);
}
public ChatArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.context = context;
}
public int getCount() {
return this.chatMessageList.size();
}
//Retrieve message position
public ChatMessage getItem(int index) {
return this.chatMessageList.get(index);
}
//Change layout inflater if necessary
public View getView(int position, View convertView, ViewGroup parent) {
ChatMessage chatMessageObj = getItem(position);
View row = convertView;
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (chatMessageObj.left) {
row = inflater.inflate(R.layout.row_messages_right, parent, false);
}else{
row = inflater.inflate(R.layout.row_messages_left, parent, false);
}
chatText = (TextView) row.findViewById(R.id.msgr);
chatText.setText(chatMessageObj.message);
return row;
}
}
MessagingServiceNotification:
public class MyFirebaseMessagingService extends FirebaseMessagingService{
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String message = remoteMessage.getData().get("message");
String from = remoteMessage.getData().get("From");
String to = remoteMessage.getData().get("to");
InternalDatabaseOperations DB = new InternalDatabaseOperations(this);
DB.putInformation(DB, from, to, message);
showNotification(message);
}
private void showNotification(String message) {
Intent i = new Intent(this, Messages.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle("BookStore")
.setContentText(message)
.setSmallIcon(R.drawable.book)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0, builder.build());
}
}
logcat:
14007-14681/gamingproject.sellmybooks E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: gamingproject.sellmybooks, PID: 14007
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6353)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:875)
at android.view.View.requestLayout(View.java:17524)
at android.view.View.requestLayout(View.java:17524)
at android.view.View.requestLayout(View.java:17524)
at android.view.View.requestLayout(View.java:17524)
at android.view.View.requestLayout(View.java:17524)
at android.view.View.requestLayout(View.java:17524)
at android.view.View.requestLayout(View.java:17524)
at android.widget.AbsListView.requestLayout(AbsListView.java:2027)
at android.widget.AbsListView.setSelectionFromTop(AbsListView.java:7045)
at android.widget.ListView.setSelection(ListView.java:2018)
at gamingproject.sellmybooks.Messages$3.onChanged(Messages.java:74)
at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286)
at android.widget.ArrayAdapter.add(ArrayAdapter.java:182)
at gamingproject.sellmybooks.ChatArrayAdapter.add(ChatArrayAdapter.java:22)
at gamingproject.sellmybooks.Messages.receiveChatMessage(Messages.java:104)
at gamingproject.sellmybooks.Messages.access$300(Messages.java:23)
at gamingproject.sellmybooks.Messages$4.run(Messages.java:83)
at java.util.Timer$TimerImpl.run(Timer.java:284)
Thank you in advance for the help.
The problem is that your Timer is using a background thread, and you're trying to update your ChatArrayAdapter from that background thread.
From the documentation:
Corresponding to each Timer object is a single background thread that
is used to execute all of the timer's tasks, sequentially.
If you keep your code as is for the Timer:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
receiveChatMessage();
}
}, 0, 1000);
It looks like you just need to put the code that adds an item to the adapter on the UI Thread:
private boolean receiveChatMessage() {
InternalDatabaseOperations DB = new InternalDatabaseOperations(this);
Cursor CR = DB.getInformation(DB);
CR.moveToLast();
from = CR.getString(0);
to = CR.getString(1);
if(!Objects.equals(mess, CR.getString(2))){
mess = CR.getString(2);
//modified:
runOnUiThread(new Runnable() {
#Override
public void run() {
chatArrayAdapter.add(new ChatMessage(!side, mess));
}
});
CR.close(); //close your cursor to avoid memory leaks!
return true;
}
CR.close(); //close your cursor to avoid memory leaks!
return false;
}
I'm trying to make a reminder app and I used the phones internal storage to store the data being inputted. How do I read the file from the internal storage and place the strings in title in the listview of ReminderListActivity.java?
ReminderListActivity.java
public class ReminderListActivity extends ListActivity {
private static final int ACTIVITY_CREATE = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_reminder_list);
String[] items = new String[]{"Title"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.reminder_row, R.id.text1, items);
setListAdapter(adapter);
registerForContextMenu(getListView());
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, ReminderEditActivity.class);
i.putExtra("RowId", id);
startActivity(i);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.list_menu_item_longpress, menu);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.list_menu, menu);
return true;
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_insert:
createReminder();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
private void createReminder() {
Intent i = new Intent(this, ReminderEditActivity.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete:
return true;
}
return super.onContextItemSelected(item);
}
public void onClickSave(View view) {
Intent f = new Intent(this, ReminderEditActivity.class);
startActivity(f);
}
}
Heres the Activity I used to save the strings into the json file in the internal storage
ReminderEditActivity.java
public class ReminderEditActivity extends Activity {
private Button mDateButton;
private Button mTimeButton;
private static final int DATE_PICKER_DIALOG = 0;
private static final int TIME_PICKER_DIALOG = 1;
private Calendar mCalendar;
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String TIME_FORMAT = "kk:m";
private static final String FILENAME = "hello.json";
private EditText TitleEditText;
private EditText BodyEditText;
private Button EditTime;
private Button EditDate;
private ArrayList<Data> data =
new ArrayList<Data>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_reminder_edit);
mCalendar = Calendar.getInstance();
mDateButton = (Button) findViewById(R.id.reminder_date);
mTimeButton = (Button) findViewById(R.id.reminder_time);
TitleEditText = (EditText) findViewById(R.id.title);
BodyEditText = (EditText) findViewById(R.id.body);
EditTime = (Button) findViewById(R.id.reminder_time);
EditDate = (Button) findViewById(R.id.reminder_date);
if (getIntent() != null) {
Bundle extras = getIntent().getExtras();
int rowId = extras != null ? extras.getInt("RowId") : -1;
registerButtonListenersAndSetDefaultText();
}
readData();
}
public void readData() {
try {
FileInputStream fis = openFileInput(FILENAME);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
JsonReader jsonReader = new JsonReader(isr);
String title = "";
String body = "";
String time = "";
String date = "";
jsonReader.beginArray(); // [
while (jsonReader.hasNext()) {
jsonReader.beginObject(); // {
while (jsonReader.hasNext()) {
String key = jsonReader.nextName();
if (key.equals("Title")) {
title = jsonReader.nextString();
} else if (key.equals("Body")) {
body = jsonReader.nextString();
} else if (key.equals("Date")) {
date = jsonReader.nextString();
} else if (key.equals("Time")) {
time = jsonReader.nextString();
}
}
jsonReader.endObject(); // }
Data content = new Data(
title, body, date, time
);
data.add(content);
}
jsonReader.endArray();
jsonReader.close();
} catch (IOException ex) {
Toast.makeText(this, "cannot read file", Toast.LENGTH_SHORT).show();
}
}
public void addFile(View view) {
String title = TitleEditText.getText().toString();
String body = BodyEditText.getText().toString();
String time = EditTime.getText().toString();
String date = EditDate.getText().toString();
Toast.makeText(this, "File written", Toast.LENGTH_SHORT).show();
Data content = new Data(
title, body, date, time
);
data.add(content);
writeAllData();
}
public void writeAllData() {
try {
FileOutputStream fos = openFileOutput(FILENAME,
Context.MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
JsonWriter jsonWriter = new JsonWriter(osw);
jsonWriter.setIndent(" ");
jsonWriter.beginArray();
for (int i = 0; i < data.size(); i++) {
Data con = data.get(i);
jsonWriter.beginObject();
jsonWriter.name("Title").value(con.GetTitle());
jsonWriter.name("Body").value(con.GetBody());
jsonWriter.name("Date").value(con.GetDate());
jsonWriter.name("Time").value(con.GetTime());
jsonWriter.endObject();
}
jsonWriter.endArray();
jsonWriter.close();
} catch (IOException ex) {
Toast.makeText(this, "Cant write file", Toast.LENGTH_LONG).show();
}
}
private void registerButtonListenersAndSetDefaultText() {
mTimeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(TIME_PICKER_DIALOG);
}
});
mDateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(DATE_PICKER_DIALOG);
}
});
updateDateButtonText();
updateTimeButtonText();
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DATE_PICKER_DIALOG:
return showDatePicker();
case TIME_PICKER_DIALOG:
return showTimePicker();
}
return super.onCreateDialog(id);
}
private DatePickerDialog showDatePicker() {
DatePickerDialog datePicker = new DatePickerDialog(ReminderEditActivity.this, new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mCalendar.set(Calendar.YEAR, year);
mCalendar.set(Calendar.MONTH, monthOfYear);
mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateDateButtonText();
}
}, mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
return datePicker;
}
private TimePickerDialog showTimePicker() {
TimePickerDialog timePicker = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
mCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
mCalendar.set(Calendar.MINUTE, minute);
updateTimeButtonText();
}
}, mCalendar.get(Calendar.HOUR_OF_DAY), mCalendar.get(Calendar.MINUTE), true);
return timePicker;
}
private void updateDateButtonText() {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
String dateForButton = dateFormat.format(mCalendar.getTime());
mDateButton.setText(dateForButton);
}
private void updateTimeButtonText() {
SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_FORMAT);
String timeForButton = timeFormat.format(mCalendar.getTime());
mTimeButton.setText(timeForButton);
}
}
Hi in the below code I am getting array index out of bounds exception.Here friend array it's giving two values.
For ex:
friendinfo[0]=user1,friendinfo1=user2 and with checkbox when i am selecting user1 I want to show friend.length to 2 and checked value should be 1.
this is sample screen how to add the use3 and user1 when i am clicking the create button.
GroupList.java
public class GroupList extends ListActivity
{
boolean[] checkBoxState;
private IAppManager imService = null;
private FriendListAdapter friendAdapter;
public String ownusername = new String();
private class FriendListAdapter extends BaseAdapter
{
#SuppressWarnings("unused")
class ViewHolder {
TextView text;
ImageView icon;
CheckBox check1;
}
private LayoutInflater mInflater;
private Bitmap mOnlineIcon;
private Bitmap mOfflineIcon;
private FriendInfo[] friends = null;
public FriendListAdapter(Context context) {
super();
mInflater = LayoutInflater.from(context);
mOnlineIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenstar);
mOfflineIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.redstar);
}
public void setFriendList(FriendInfo[] friends)
{
this.friends = friends;
}
public int getCount() {
return friends.length;
}
public FriendInfo getItem(int position) {
return friends[position];
}
public long getItemId(int position) {
return 0;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.grouplist, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.check1 = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(friends[position].userName);
holder.icon.setImageBitmap(friends[position].status == STATUS.ONLINE ? mOnlineIcon : mOfflineIcon);
checkBoxState = new boolean[friends.length];
holder.check1.setChecked(checkBoxState[position]);
holder.check1.setOnCheckedChangeListener(new OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checkBoxState[position]=isChecked;
String check=friends[position].userName;
Toast.makeText(getApplicationContext(),friends[position].userName+"checked", Toast.LENGTH_LONG).show();
}
});
return convertView;
}
}
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Broadcast receiver ", "received a message");
Bundle extra = intent.getExtras();
if (extra != null)
{
String action = intent.getAction();
if (action.equals(IMService.FRIEND_LIST_UPDATED))
{
GroupList.this.updateData(FriendController.getFriendsInfo(),
FriendController.getUnapprovedFriendsInfo());
}
}
}
};
public MessageReceiver messageReceiver = new MessageReceiver();
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((IMService.IMBinder)service).getService();
FriendInfo[] friends = FriendController.getFriendsInfo();
if (friends != null) {
GroupList.this.updateData(friends, null);
}
String groupname = getIntent().getStringExtra("nick");
setTitle(groupname);
ownusername = imService.getUsername();
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
Toast.makeText(GroupList.this, R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
}
};
#SuppressLint("NewApi")
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}
setContentView(R.layout.group_list_screen);
friendAdapter = new FriendListAdapter(this);
Button create=(Button)findViewById(R.id.create);
create.setOnClickListener(new OnClickListener() {
#SuppressWarnings("unused")
#Override
public void onClick(View v) {
String groupname = getIntent().getStringExtra("nick");
try {
FriendInfo[] friend=FriendController.getFriendsInfo();
//checkBoxState = new CheckBox[friend.length];
/*try {
for(int i=0;i <=friend.length ;i++){
if(checkBoxState[i].isChecked()){
check[i]="1";
}
}
}catch (Exception e) {
e.printStackTrace();
}*/
String result1 = imService.CreateGroup(groupname,imService.getUsername(),friend);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Group Created Sucessfully",Toast.LENGTH_LONG).show();
}
});
}
public void updateData(FriendInfo[] friends, FriendInfo[] unApprovedFriends)
{
if (friends != null) {
friendAdapter.setFriendList(friends);
setListAdapter(friendAdapter);
}
if (unApprovedFriends != null)
{
NotificationManager NM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (unApprovedFriends.length > 0)
{
String tmp = new String();
for (int j = 0; j < unApprovedFriends.length; j++) {
tmp = tmp.concat(unApprovedFriends[j].userName).concat(",");
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.stat_sample)
.setContentTitle(getText(R.string.new_friend_request_exist));
/*Notification notification = new Notification(R.drawable.stat_sample,
getText(R.string.new_friend_request_exist),
System.currentTimeMillis());*/
Intent i = new Intent(this, UnApprovedFriendList.class);
i.putExtra(FriendInfo.FRIEND_LIST, tmp);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
i, 0);
mBuilder.setContentText("You have new friend request(s)");
mBuilder.setContentIntent(contentIntent);
NM.notify(R.string.new_friend_request_exist, mBuilder.build());
}
else
{
NM.cancel(R.string.new_friend_request_exist);
}
}
}
#Override
protected void onPause()
{
unregisterReceiver(messageReceiver);
unbindService(mConnection);
super.onPause();
}
#Override
protected void onResume()
{
super.onResume();
bindService(new Intent(GroupList.this, IMService.class), mConnection , Context.BIND_AUTO_CREATE);
IntentFilter i = new IntentFilter();
i.addAction(IMService.FRIEND_LIST_UPDATED);
registerReceiver(messageReceiver, i);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
You probably wanted to write :
if(checkBoxState[i]==isChecked)
if checkBoxState and friend arrays have the same length, checkBoxState[friend.length] is out of bounds, since the indices of an array are from 0 to length - 1.
Also note that your if condition contained an assignment operator = instead of a comparison operator ==.
Just use the index inside the for loop. Also since isChecked is already a boolean you can just assign it directly to checkBoxState
for (int i = 0; i < friend.length; i++) {
checkBoxState[i] = isChecked;
}
You are trying to access the index 2nd position in an array that has only a length of 2 (positions 0 and 1).
So please change the code as below,
if(checkBoxState[i]==isChecked)
I am having trouble carrying over a user selected image/gif to the main LWP service. I start off by prompting the user to select a gif through this PreferenceActivity (some of this was borrowed from members here and tutorials on Vogella)
public class GifPreference extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener{
#SuppressWarnings("deprecation")
//SharedPreferences SHARED_PREF;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName("custom_gif");
addPreferencesFromResource(R.xml.prefsettings);
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(
this);
getPreferenceManager().findPreference("custom_gif").setOnPreferenceClickListener(new OnPreferenceClickListener()
{
public boolean onPreferenceClick(Preference preference)
{
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Toast.makeText(getBaseContext(), "Select a GIF - " + (width) + " x " + height , Toast.LENGTH_LONG).show();
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, 1);
return true;
}
});
}
public String getRealPathFromURI(Uri contentUri) {
String [] proj={MediaColumns.DATA};
Cursor cursor = managedQuery( contentUri,
proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
String RealPath;
SharedPreferences customSharedPreference = getSharedPreferences("custom_gif", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = customSharedPreference.edit ();
RealPath = getRealPathFromURI (selectedImage);
editor.putString("custom_gif", RealPath);
editor.commit();
ComponentName component = new ComponentName(getPackageName(), getPackageName() + ".LWPEngine");
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, component);
startActivity(intent);
}}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onDestroy() {
getPreferenceManager().getSharedPreferences().
unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
}
}
And this is the main LWPService:
public class LWPEngine extends WallpaperService {
private static int RESULT_LOAD_IMAGE1 = 1;
static final Handler mGIFHandler = new Handler();
//public String gifBG;
public Engine onCreateEngine() {
try {
LWPEngine.GIFEngine var1 = new LWPEngine.GIFEngine();
return var1;
} catch (IOException var3) {
return null;
}
}
class GIFEngine extends Engine {
private LWPEngineHelper lWPEngineHelper = new LWPEngineHelper(LWPEngine.this.getApplicationContext(), LWPEngine.this.getResources());
private final Movie mGIF;
private final int mGIFDuration;
private final int mGIFHeight;
private final Runnable mGIFRunnable;
private final int mGIFWidth;
private String mImageScale = "Stretch to screen";
private long mStart;
private int mWhen;
#SuppressWarnings("unused")
public GIFEngine() throws IOException {
//decodes and plays the gif - if no gif is found, throw an error.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(LWPEngine.this);
String gifBG = prefs.getString("custom_gif", "This file does not work");
InputStream var2 = new FileInputStream(gifBG);
//InputStream var2 = LWPEngine.this.getResources().openRawResource(R.drawable.dogegif);
if(var2 != null) {
try {
this.mGIF = Movie.decodeStream(var2);
this.mGIFDuration = this.mGIF.duration();
} finally {
var2.close();
}
this.mGIFWidth = this.mGIF.width();
this.mGIFHeight = this.mGIF.height();
this.mWhen = -1;
this.mGIFRunnable = new Runnable() {
public void run() {
GIFEngine.this.animGIF();
}
};
} else {
throw new IOException("Can't open GIF");
}
}
void animGIF()
{
tick();
SurfaceHolder localSurfaceHolder = getSurfaceHolder();
Canvas localCanvas = null;
/* try
{*/
localCanvas = localSurfaceHolder.lockCanvas();
if (localCanvas != null)
animGIFDraw(localCanvas);
if (localCanvas != null)
localSurfaceHolder.unlockCanvasAndPost(localCanvas);
LWPEngine.mGIFHandler.removeCallbacks(this.mGIFRunnable);
if (isVisible())
LWPEngine.mGIFHandler.postDelayed(this.mGIFRunnable, 40L);
return;
/* }
finally
{
if (localCanvas != null)
localSurfaceHolder.unlockCanvasAndPost(localCanvas);
}*/
}
void animGIFDraw(Canvas var1) {
this.lWPEngineHelper.setBackground(var1);
var1.save();
PointF var3 = this.lWPEngineHelper.getCanvasScale(this.mImageScale, this.mGIFWidth, this.mGIFHeight);
var1.scale(var3.x, var3.y);
this.mGIF.setTime(this.mWhen);
Point var5 = this.lWPEngineHelper.getImagePos(var3, this.mGIFWidth, this.mGIFHeight);
this.mGIF.draw(var1, (float)var5.x, (float)var5.y);
var1.restore();
}
public void onDestroy() {
super.onDestroy();
LWPEngine.mGIFHandler.removeCallbacks(this.mGIFRunnable);
}
public void onOffsetsChanged(float var1, float var2, float var3, float var4, int var5, int var6) {
super.onOffsetsChanged(var1, var2, var3, var4, var5, var6);
this.animGIF();
}
public void onSurfaceChanged(SurfaceHolder var1, int var2, int var3, int var4) {
super.onSurfaceChanged(var1, var2, var3, var4);
this.animGIF();
}
public void onVisibilityChanged(boolean var1) {
super.onVisibilityChanged(var1);
if(var1) {
this.animGIF();
} else {
LWPEngine.mGIFHandler.removeCallbacks(this.mGIFRunnable);
}
}
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
String gifBG = prefs.getString("custom_gif", "This file does not work");
//gifBG = prefs.getString("custom_gif", "Bad Image");
}
void tick() {
if((long)this.mWhen == -1L) {
this.mWhen = 0;
this.mStart = SystemClock.uptimeMillis();
} else {
if(this.mGIFDuration!=0) {
this.mWhen = (int)((SystemClock.uptimeMillis() - this.mStart) % (long)this.mGIFDuration);
}
}
}
}
}
I keep getting a null pointer exception - I'm guess because there's nothing there - so I'm obviously not setting the shared preferences right - or it's the inputstream...
Any help in getting a user selected image to the inputstream of the main LWPservice would be very helpful!
**Edit I should mention everything works up until I start the LWPService after selecting the GIF. It's when loading the lwp I get the error. using a static GIF in the drawable does work.
Thanks in advanced,
Marc
I figured out the answer in case anyone is curious.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(LWPEngine.this);
String gifBG = prefs.getString("custom_gif", "This file does not work");
needs to be:
SharedPreferences prefs = getApplicationContext().getSharedPreferences("custom_gif",MODE_PRIVATE);
String gifBG = prefs.getString("custom_gif", "This file does not work");
Also needed to change this in my SharedPreference class as well.
getSharedPreference needs context, and the way I had it before for was limiting the scope of the "global" capabilities of the SharedPreference method.
I hope that helps people!
I have an adapter that extends FragmentPagerAdapter and takes advantage of the ICS style actionBar. This actionbar has actions that take input from the currently selected page.
Specifically, I have a screenshot icon in the actionbar that takes the url of the current page and displays any screenshots from that url. However, I dont know how to retrieve the currently selected page.
How can I implement something like a
public int getActivePage() {
return position;
Im still working on the viewpager implementation, so my code is still heavily reliant on examples, so disregard the mess :P
The problem areas are marked below.
public class ListFragmentViewPagerActivity extends FragmentActivity {
ArrayList<String> URLS;
ArrayList<String> TITLES;
BroadcastReceiver receiver;
String threadTitle = null;
public static String threadUrl = null;
String type = null;
String threadAuthor = null;
String ident = null;
boolean isFav = false;
String author = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.thread_view);
Bundle extras = getIntent().getExtras();
threadTitle = extras.getString("title");
threadUrl = extras.getString("url");
type = extras.getString("type");
ident = extras.getString("ident");
author = extras.getString("author");
try {
URLS = extras.getStringArrayList("urls");
TITLES = extras.getStringArrayList("titles");
} catch (Exception e) {
URLS = null;
}
final FDBAdapter db = new FDBAdapter(this);
db.open();
Cursor c = db.getAllFavs();
if (c.getCount()>0) {
if (c.getString(2).equals(threadTitle)) {
isFav = true;
}
try {
while (c.moveToNext()) {
Log.d("FAVS", c.getString(2));
if (c.getString(2).equals(threadTitle)) {
isFav = true;
}
}
} catch (Exception ep) {
ep.printStackTrace();
}
}
c.close();
db.close();
ViewPager pager = (ViewPager) findViewById(android.R.id.list);
pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager()));
TitlePageIndicator indicator = (TitlePageIndicator)findViewById( R.id.indicator );
indicator.setViewPager(pager);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
int icon = R.drawable.ic_launcher; // icon from resources
CharSequence tickerText = "Download ready!"; // ticker-text
long when = System.currentTimeMillis(); // notification time
CharSequence contentTitle = "OMG"; // expanded message title
CharSequence contentText = "Your download is finished!"; // expanded message text
Intent notificationIntent = new Intent(context, ExampleListFragment.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
final int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);
}
}
};
registerReceiver(receiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
public class ExamplePagerAdapter extends FragmentPagerAdapter implements TitleProvider{
public ExamplePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return URLS.size();
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new ExampleListFragment();
// set arguments here, if required
Bundle args = new Bundle();
args.putString("url", URLS.get(position));
fragment.setArguments(args);
return fragment;
}
#Override
public String getTitle(int pos) {
return TITLES.get(pos);
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuinflate = new MenuInflater(this);
menuinflate.inflate(R.menu.thread_menu, menu);
if (type.equals("xda")) {
menu.removeItem(R.id.ss_view);
}
if (isFav) {
menu.getItem(2).setIcon(R.drawable.fav_ab);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
break;
case R.id.ss_view:
Intent ssi = new Intent(this, SSActivity.class);
ssi.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle b = new Bundle();
//I need to get the position of the currently active page here so that I can retrieve the //corresponding values for the title and url.
b.putString("title", threadTitle);
b.putString("url", threadUrl);
ssi.putExtras(b);
startActivity(ssi);
break;
case R.id.restart:
break;
case R.id.fav_ab:
threadUrl = new String(threadUrl.replaceAll("http://", ""));
FDBAdapter fdb = new FDBAdapter(this);
fdb.open();
if (isFav) {
Cursor c = fdb.getAllUrls();
while (c.moveToNext()) {
String id = c.getString(c.getColumnIndex("_id"));
int rowId = Integer.parseInt(id);
if(c.getString(c.getColumnIndex("url")).equals(threadUrl)) {
if (fdb.deleteUrl(rowId)) {
Log.d("THREAD", "SUCCESS");
} else {
Log.d("THREAD", "FAILED");
}
}
}
c.close();
item.setIcon(R.drawable.fav_ab_off);
isFav = false;
} else {
fdb.insertFav(threadUrl, threadTitle, ident, type, author, "thread");
item.setIcon(R.drawable.fav_ab);
isFav = true;
}
fdb.close();
default:
return super.onOptionsItemSelected(item);
}
return false;
}
#Override
public void onStop() {
super.onStop();
unregisterReceiver(receiver);
}
#Override
public void onStart() {
super.onStart();
registerReceiver(receiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
}
Heres what I mean by the currently selected page.
I believe what you are looking for is onPageChangedListener(). This method belongs to the TitlePageIndicator. Something like...
indicator.setOnPageChangedListener(new OnPageChangedListener() {
// Implement unimplemented methods...
});
you can also ask to viewpager
in java
ViewPager pager = (ViewPager) findViewById(android.R.id.list);
pager.getCurrentItem()
in kotlin
pager.currentItem