I am using StandOutWindow library.
In my Setting screen,I have a switch (turn on/off). If I turn on switch, a popup and a notification are displayed.
When I turn off switch, popup isn't display.
I wanna, when I click on notification, popup is hidden and switch has "OFF" status. Now,I only do popup is hidden. Switch also has "ON" status. How to I can turn off switch.
I tried write code in getPersistentNotificationIntent but can not.
Here is my code:
public class TogglePopup extends StandOutWindow {
public View view;
#Override
public String getAppName() {
return "JSDict";
}
#Override
public int getAppIcon() {
return android.R.drawable.ic_menu_close_clear_cancel;
}
#SuppressLint("NewApi")
#Override
public void createAndAttachView(int id, final FrameLayout frame) {
// create a new layout from body.xml
final LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.popup_toggle, frame, true);
ToggleButton toggle = (ToggleButton) view
.findViewById(R.id.toggle_popup);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
LinearLayout viewLinear = (LinearLayout) view
.findViewById(R.id.toggle_popup_background);
if (isChecked) {
// The toggle is enabled
viewLinear
.setBackgroundResource(R.drawable.popup_toggle_on);
ComponentName service = getApplicationContext()
.startService(
new Intent(getApplicationContext(),
ClipboardMonitor.class));
StandOutWindow.closeAll(getApplicationContext(),
ClipboardMonitor.class);
StandOutWindow.show(getApplicationContext(),
ClipboardMonitor.class, StandOutWindow.DEFAULT_ID);
} else {
// The toggle is disabled
viewLinear
.setBackgroundResource(R.drawable.popup_toggle_off);
getApplicationContext().stopService(
new Intent(getApplicationContext(),
ClipboardMonitor.class));
StandOutWindow.closeAll(getApplicationContext(),
ClipboardMonitor.class);
}
}
});
}
// the window will be centered
#Override
public StandOutLayoutParams getParams(int id, Window window) {
return new StandOutLayoutParams(id, 250, 300,
StandOutLayoutParams.CENTER, StandOutLayoutParams.CENTER);
}
// move the window by dragging the view
#Override
public int getFlags(int id) {
return super.getFlags(id) | StandOutFlags.FLAG_BODY_MOVE_ENABLE
| StandOutFlags.FLAG_WINDOW_FOCUSABLE_DISABLE;
}
#Override
public String getPersistentNotificationMessage(int id) {
return "Click to close the JSDict";
}
#Override
public Intent getPersistentNotificationIntent(int id) {
return StandOutWindow.getCloseIntent(this, TogglePopup.class, id);
/*
* StandOutWindow.show(this, WidgetsWindow.class,
* StandOutWindow.DEFAULT_ID);
*/
}
}
There needs to be a single persistent notification for the StandOut service, or else android will kill your service on low memory (which happens every 5 seconds). You are mistaken about the fact that there is a new persistent notification for each new window. Unless you have multiple types, you will only have one persistent notification no matter how many windows the user opens. If multiple types are an issue, look at FloatingFolders for how to implement multiple types in a single service.
Related
As the title says, I'm developing an android application. I have a recyclerview that renders my app list and a context menu with the options "Unintstall app" and "App info". The App Info button should just open up the android settings page of the application itself, where the user can uninstall, clear cache, change permissions etc.
How do I go about to do this? Is it through some method in packagemanager? Do I need any special permissions for this?
Here's the code that handles the context menu selections in my app drawer class:
#Override
public boolean onContextItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case 1: // add to favourites in homescreen
displayMessage("Added to Favourites");
return true;
case 2: // show information about app
return true;
case 3: // uninstall application
displayMessage("Uninstalled application");
return true;
// delete this later, it's supposed to be an unreachable message
default:
displayMessage("You should not be seeing this message");
}
return super.onContextItemSelected(item);
}
And here is the relevant code in the recyclerview:
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener {
public TextView appNameTV;
public ImageView appIconIV;
public TextView appCategoryTV;
public LinearLayout appDrawerItemLL;
//This is the subclass ViewHolder which simply
//'holds the views' for us to show on each row
public ViewHolder(View itemView) {
super(itemView);
//Finds the views from our row.xml
appNameTV = (TextView) itemView.findViewById(R.id.applicationNameTextView);
appIconIV = (ImageView) itemView.findViewById(R.id.applicationIconImageView);
appCategoryTV = (TextView) itemView.findViewById(R.id.appCategory);
appDrawerItemLL = (LinearLayout) itemView.findViewById(R.id.app_drawer_item);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
#Override
public void onClick (View v) {
int pos = getAdapterPosition();
Context context = v.getContext();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(appsList.get(pos).getPackageName());
context.startActivity(launchIntent);
//Toast.makeText(v.getContext(), appsList.get(pos).getName(), Toast.LENGTH_LONG).show();
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.add(this.getAdapterPosition(), 1, 0, "Add to Favourites");
menu.add(this.getAdapterPosition(), 2, 1, "App info");
menu.add(this.getAdapterPosition(), 3, 2, "Uninstall app");
}
}
public void addApp(AppObject app) {
appsList.add(app);
}
You need this permission in your manifest:
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
Here is a static method to uninstall any package (protected system or device manufacturer apps will not work). User will always be promted to agree so no forced deinstallation is possible.
public static boolean deinstallApp(Context appContext,String packageName)
{
try {
Uri apkUri = Uri.parse("package:" + packageName);
Intent intent = new Intent(Intent.ACTION_DELETE, apkUri);
appContext.startActivity(intent);
return true;
}catch (Exception e)
{
Log.e("deinstallApp"," error uninstalling. package not found?!");
}
return false;
}
I have a recycler view in my activity. I implement an Interface in this activity that has to show keyboard when the user, touching a specific item in recycler view and send item position item that user touched into Activity.
This is my Interface:
public interface ReplyAction {
void onEvent(Context context , int courseId);
}
This is my interface method that i called in acivity:
#Override
public void onEvent(final Context mContext, int courseId) {
replyTo = courseId;
etMessage = (EditText) ((Activity) mContext).findViewById(R.id.etMessage);
etMessage.setFocusable(true);
//Show Keyboard to user
InputMethodManager imm = (InputMethodManager) getSystemService(mContext.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
but I will get this error:
FATAL EXCEPTION: main
Process: codenevisha.com.apps.learningmanagementsystem, PID: 7098
java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:5774)
at codenevisha.com.apps.learningmanagementsystem.activity.ActivityCourseChat.onEvent(ActivityCourseChat.java:547)
at codenevisha.com.apps.learningmanagementsystem.adapter.chatAdapter$1.onClick(chatAdapter.java:240)
This is Where I call OnEvent Method that is in my recycler view adapter:
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
String question;
String answer;
switch (holder.getItemViewType()) {
case 1: //For item message text left
question = chatArray.get(position).getCourseForumModel().getCourseForumQuestion();
answer = chatArray.get(position).getCourseForumModel().getCourseForumAnswer();
ViewHolderLeftText vLText = (ViewHolderLeftText) holder;
vLText.txtQuestion.setText(question);
if (!answer.equals("")) {
if (chatArray.get(position).getCourseForumModel().getCourseForumAUser().equals(G.userId)) {
//This Answer is prepared by this user
vLText.answerLayout.setBackgroundColor(mContext.getResources().getColor(R.color.my_message_background_color));
}
vLText.txtAnswer.setText(answer);
//Handling reply message to this message
vLText.imgReplay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCourseChat a = new ActivityCourseChat();
a.onEvent(mContext , chatArray.get(position).getCourseForumModel().getCourseForumId());
}
});
}
break;
case 2: //For item message image left
ViewHolderLeftImage vLImage = (ViewHolderLeftImage) holder;
//Handling reply message to this message
vLImage.imgReply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCourseChat a = new ActivityCourseChat();
a.onEvent(mContext ,chatArray.get(position).getCourseForumModel().getCourseForumId());
}
});
break;
}
ActivityCourseChat a = new ActivityCourseChat();
NEVER create an instance of an activity yourself. Delete both occurrences of this line. Then, get your ActivityCourseChat instance some other way. For example, if this RecyclerView.Adapter is being used by ActivityCourseChat, pass in the ActivityCourseChat instance via a constructor parameter.
I have a very strange situation. I am using Contextual Action Mode for selecting multiple items of the ListView. The flow goes as follows:
User selects the list items using long press on them --> Uses the action item "Operations" to choose what he wants to do --> This action item creates a AlertDialog with 4 list items (call it dialog1) where the 3rd item calls another AlertDialog (call it dialog2) which includes an EditText for some data input and later calls a method to perform it.
Later the user hits Back button or Home button to exit the Action Mode.
The problem is that dialog2 shows up alternatively like first time user selects the list items, Chooses "Operations" action item and chooses the 3rd item which calls dialog2. Now dialog2 will appear as it is supposed to. Later the user hits the Back button to quit the Action Mode.
The SECOND TIME user performs the same steps dialog2 doesn't appear.
The logcat shows this error in both the cases:
09-04 10:53:12.096 6299-6299/com.project.pcmanager
W/InputEventReceiver: Attempted to finish an input event but the input
event receiver has already been disposed.
Some code:
public void sendAction(final Context context, final EventModel model, int position) {
JSONObject object = new JSONObject();
String[] operations = getResources().getStringArray(R.array.operations);
// null set before is modified here
model.setEventTitle(operations[position]);
final String ip = model.getEventIP();
switch (position) {
case 0:
try {
object.put("command", "power_off");
notifyUser();
LogUtils.addEntry(model.toString());
execCommand(ip,object);
} catch (JSONException e) {
e.printStackTrace();
}
break;
case 1:
try {
object.put("command", "reboot");
notifyUser();
LogUtils.addEntry(model.toString());
execCommand(ip,object);
} catch (JSONException e) {
e.printStackTrace();
}
break;
case 2:
//Show AlertDialog with EditText on it for command input
final EditText txtCommand = new EditText(context);
// Set some properties to EditText
txtCommand.setPadding(16, 16, 16, 16);
txtCommand.setMinHeight(150);
txtCommand.setHint("Ex: ping google.com");
txtCommand.setSingleLine();
new AlertDialog.Builder(context)
.setTitle("Run a task")
.setView(txtCommand)
.setCancelable(false)
.setPositiveButton("Run",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String command = txtCommand.getText().toString();
if (command.length() > 0) {
JSONObject object = new JSONObject();
try {
object.put("run", command);
object.put("ip", ip);
notifyUser();
LogUtils.addEntry(model.toString());
performRemoteExec(object);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(context, "Please provide a command first!", Toast.LENGTH_SHORT).show();
}
}
}).setNeutralButton("Cancel", null).show();
break;
case 3:
notifyUser();
LogUtils.addEntry(model.toString());
getScreenshot(ip);
break;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
listView.setAdapter(adapter);
listView.setEmptyView(emptyView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
//Change the title bar with the items selected
mode.setTitle(listView.getCheckedItemCount() + " selected");
//select the clicked item
adapter.toggleSelection(position);
}
/**
* Called when action mode is first created.
* The menu supplied will be used to generate action buttons for the action mode.
* #param mode ActionMode being created
* #param menu Menu used to populate action buttons
* #return true if the action mode should be created,
* false if entering this mode should be aborted.
*/
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
onContextMode = true;
mode.getMenuInflater().inflate(R.menu.menu_client_select_main, menu);
return true;
}
/**
* Called to refresh an action mode's action menu whenever it is invalidated.
* #return true if the menu or action mode was updated, false otherwise.
*/
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
/**
* Called to report a user click on an action button.
* #return true if this callback handled the event,
* false if the standard MenuItem invocation should continue.
*/
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_operations) {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setItems(R.array.operations, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SparseBooleanArray selectedIds = adapter.getSelectedIds();
// traverse the array to find chosen clients
for (int i = 0; i < selectedIds.size(); i++) {
if (selectedIds.get(i)) {
ClientModel item = adapter.getItem(i);
String ip = item.getClientIP();
String os = item.getOSType();
// null will be treated soon
EventModel model = new EventModel(ip, null, os);
sendAction(builder.getContext(),model, which);
}
}
}
});
builder.show();
}
return true;
}
/**
* Called when an action mode is about to be exited and destroyed.
*/
#Override
public void onDestroyActionMode(ActionMode mode) {
onContextMode = false;
}
});
}
Ok so I figured the problem myself. It turns out the culprit was me using SparseBooleanArray to get selected clients and I was wrong.
In my code it was:
SparseBooleanArray selectedIds = adapter.getSelectedIds();
So, I removed this SparseBooleanArray with a new implementation technique. I used ArrayList<ClientMode> selectedItems to store all the selected models in my Adapter class.
Also, I created a simple method called clearSelections that calls selectedItems.clear() method in it. I call this method at on onDestroyActionMode as per my app requirement.
HOW I FOUND THIS?
I simply placed a bunch of System.out.println statements all around onCreate and sendAction to find out the culprit.
Context
I'm working with popupwindows to allow a user to quickly rename a cardview in an activity.
I do this by using a ViewSwitcher to swap the TextView (original name) for an EditText(new name).
Problem
When the EditText and PopUpWindow to confirm are present an the user presses "RECENT APPS", you cannot for some reason get back into the app. ie. when you click it, it won't respond.
Diagnosis
I think it's an issue with Window Focus. I've tried EditText.clearFocus() from ET and dismissing all PopUps onPause, no luck.
Is there a way to use onFocusChangeListener to remove this issue?
Code (I've tried to remove as much superfluous items as possible)
TheHubActivity.java
public class TheHubActivity extends AppCompatActivity implements RecyclerViewAdapter.onCardClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
// KEYBOARD
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//... Set up recycle view
rvContent = new ArrayList<>();
}
#Override
public void onCardLongClick(Flow longClickedFlow, int cardPosition, View cardViewClicked) {
showLongClickPopUpMenu(longClickedFlow,cardPosition, cardViewClicked);
}
private void showLongClickPopUpMenu(final Flow longClickedFlow, final int cardPosition, final View cardViewClicked) {
LayoutInflater layoutInflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.popup_window_longclick, null);
LinearLayout viewGroup = (LinearLayout) layout.findViewById(R.id.popup_longclick);
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(layout, RecyclerView.LayoutParams.WRAP_CONTENT,
RecyclerView.LayoutParams.WRAP_CONTENT);
popup.setFocusable(true);
// Getting a reference to Close button, and close the popup when clicked.
ImageView delete = (ImageView) layout.findViewById(R.id.popup_delete_item);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*.... Delete current Flow from internal file and UI */
popup.dismiss();
}
});
ImageView edit = (ImageView) layout.findViewById(R.id.popup_edit_item);
edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popup.dismiss();
renameFlow(cardPosition, cardViewClicked);
}
});
// Displaying the popup at the specified location, + offsets.
popup.showAsDropDown(cardViewClicked, cardViewClicked.getMeasuredWidth(),popupDisplayHeight, Gravity.TOP);
longClickPopup = popup;
}
private void renameFlow(final int cardPosition, final View cardViewClicked) {
final ViewSwitcher switcher = (ViewSwitcher) cardViewClicked.findViewById(R.id.rename_switcher);
final EditText rename = (EditText) switcher.findViewById(R.id.item_flow_rename);
rename.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (rename.hasFocus()) {
showEditPopupWindow(rename, cardViewClicked, switcher, cardPosition);
} else {
imm.hideSoftInputFromWindow(rename.getWindowToken(), 0);
}
}
});
switcher.showNext();
rename.requestFocus();
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
/* Forces keyboard */
}
private void showEditPopupWindow(final EditText newName, View cardViewClicked, final ViewSwitcher switcher, final int cardPosition) {
LayoutInflater layoutInflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.popup_window_editing, null);
LinearLayout viewGroup = (LinearLayout) layout.findViewById(R.id.popup_editing);
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(layout, RecyclerView.LayoutParams.WRAP_CONTENT,
RecyclerView.LayoutParams.WRAP_CONTENT);
popup.setFocusable(false); // So that user can edit text
// Getting a reference to Close button, and close the popup when clicked.
ImageView confirmEdit = (ImageView) layout.findViewById(R.id.popup_confirm_item_changes);
confirmEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* .. Changes name of cardview through edit text */
switcher.showNext();
popup.dismiss();
newName.clearFocus();
}
}
});
ImageView cancelEdit = (ImageView) layout.findViewById(R.id.popup_cancel_item_changes);
cancelEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switcher.showNext();
popup.dismiss();
}
});
popup.showAsDropDown(cardViewClicked, cardViewClicked.getMeasuredWidth(),popupDisplayHeight, Gravity.TOP);
editingPopup = popup;
}
#Override
protected void onPause() {
dismissPopups();
super.onPause();
}
private void dismissPopups() {
if (longClickPopup!=null && longClickPopup.isShowing()) {
longClickPopup.dismiss();
}
if (editingPopup!=null && editingPopup.isShowing()) {
editingPopup.dismiss();
}
}
}
For Visual People
I solved the issue... and it was surprisingly larger and completely unrelated to the Focus/PopUps (tunnel vision does that I guess).
In my Manifest I was using android:launchMode="singleTop" which was creating weird behaviour when TheHubActivity was sent to recent apps because this was my entrance activity. From the Developer Docs singleTop functions like so:
Similarly, a new instance of a "singleTop" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent() call); a new instance is not created. In other circumstances — for example, if an existing instance of the "singleTop" activity is in the target task, but not at the top of the stack, or if it's at the top of a stack, but not in the target task — a new instance would be created and pushed on the stack.
<activity
android:name=".TheHubActivity"
android:label="#string/app_name"
~~~~~~android:launchMode="singleTop"~~~~~~~~
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
(Sorry for my mistakes in spelling)
I have a problem in the combination of some things:
I use a GridView to download show content from a database. onClick a file is downloaded which can be viewed later. Its about 20MB. This download is done by a service.
Every item in the gridView contains a progressbar in the layout. this progressbar is just shown if the item is donwloading in the background via the service.
The Service sends a broadcast about the download Progress, the Intent contains the ID of the item to find it in data of the Adapter for the gridview.
A BroadcastReceiver ist registered in my Activity to get the Progress Update (remember, simultaneous downloads are possible) which calls a function "setProgress" in the gridview-adapter
public void setProgress(long id, int progress)
{
for (int i = 0;i < list.size();i++)
{
if (list.get(i).getId() == id)
{
list.get(i).setProgress(progress);
notifyDataSetChanged();
}
}
}
To this point everything works fine.
Additionally im using QuickAction implementation from http:// www. londatiga.net/it/how-to-create-quickaction-dialog-in-android/ (Spaces because i cannot post more than two hyperlinks)
Now comes the problem:
Sometimes, i guess when notifydatasetchanged is called and the user taps on an item, the quickaction is shown on a wrong position.
To make this clearer here are two pictures:
The first one is what should happen (in this case a click on the first item of the gridview)
http://dl.dropbox.com/u/9031500/expected.png
The second picture shows what happens sometimes (only when some downloads are running, thats why i guess its because of the "notifydatasetchanged" and the rebuild of the views). This was also a click on the first item, unfortunately the quick-action is shown to the fourth item:
http://dl.dropbox.com/u/9031500/wrong.png
This is my implementation in my activity for the call of the quick-action:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
showQuickAction(view, position);
}
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
showQuickAction(view, position);
return true;
}
private void showQuickAction(View view, int position)
{
RelativeLayout facsimile = (RelativeLayout) view.findViewById(R.id.lib_item_image_layout);
Log.i(LOGTAG, "Position:"+position);
currentPaper = TZReader.paperDao.load(libraryAdapter.getItemId(position));
Log.i(LOGTAG,"Set CurrentPaper:"+currentPaper.getTitelWithDate());
ActionItem downloadItem = new ActionItem(ACTION_ITEM_DOWNLOAD, "Download", getResources().getDrawable(R.drawable.ic_action_download));
ActionItem readItem = new ActionItem(ACTION_ITEM_READ, "Lesen", getResources().getDrawable(R.drawable.ic_action_read));
ActionItem deleteItem = new ActionItem(ACTION_ITEM_DELETE, "Löschen", getResources().getDrawable(R.drawable.ic_action_delete));
ActionItem cancelItem = new ActionItem(ACTION_ITEM_CANCEL, "Abbrechen", getResources().getDrawable(R.drawable.ic_action_cancel));
QuickAction mQuickAction = new QuickAction(this, QuickAction.HORIZONTAL);
switch (currentPaper.getState())
{
case Paper.DOWNLOADED_READABLE:
mQuickAction.addActionItem(readItem);
mQuickAction.addActionItem(deleteItem);
break;
case Paper.DOWNLOADED_BUT_UPDATE:
mQuickAction.addActionItem(downloadItem);
mQuickAction.addActionItem(deleteItem);
break;
case Paper.IS_DOWNLOADING:
mQuickAction.addActionItem(cancelItem);
break;
case Paper.NOT_DOWNLOADED:
mQuickAction.addActionItem(downloadItem);
break;
}
//Set listener for action item clicked
mQuickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
#Override
public void onItemClick(QuickAction source, int pos, int actionId) {
//here we can filter which action item was clicked with pos or actionId parameter
switch(actionId)
{
case ACTION_ITEM_DOWNLOAD:
Intent downloadIntent = new Intent(getApplicationContext(), DownloadService.class);
downloadIntent.putExtra(DownloadService.PARAMETER_PAPER_DB_ID_LONG, currentPaper.getId());
startService(downloadIntent);
break;
case ACTION_ITEM_READ:
break;
case ACTION_ITEM_DELETE:
DeleteAlertDialogFragment newFragment = DeleteAlertDialogFragment.newInstance(currentPaper.getId());
newFragment.setStyle(SherlockDialogFragment.STYLE_NO_TITLE,0);
newFragment.show(getSupportFragmentManager(), "dialog");
break;
case ACTION_ITEM_CANCEL:
break;
}
}
});
mQuickAction.show(facsimile);
}
Maybe someone has any idea or hints for me how i can handle this problem!
Thanks a million in advance!
I found a solution for my problem.
The solution is that i implement my own ProgressBar, which contains now a BroadcastListerner and set the progress on each item. So i can change the value without need to call "notifydatasetchanged". perfect for my needs. Im still not sur if this is a good solution, but it works well.
Here is the code for the Progressbar:
public class ListeningProgressBar extends ProgressBar {
public ListeningProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
final IntentFilter intentDownloadProgressFilter = new IntentFilter(DownloadService.DOWNLOAD_PROGRESS_BROADCAST);
private long paperId = 0;
private boolean isReceiverRegistered = false;
#Override
protected void onAttachedToWindow() {
getContext().getApplicationContext().registerReceiver(downloadProgressBroadcastReceiver,intentDownloadProgressFilter);
isReceiverRegistered = true;
super.onAttachedToWindow();
}
#Override
protected void onDetachedFromWindow() {
if (isReceiverRegistered)
{
getContext().getApplicationContext().unregisterReceiver(downloadProgressBroadcastReceiver);
isReceiverRegistered = false;
}
super.onDetachedFromWindow();
}
private BroadcastReceiver downloadProgressBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(DownloadService.PARAMETER_PAPER_DB_ID_LONG, -1);
int progressValue = intent.getIntExtra(DownloadService.PARAMETER_PAPER_PROGRESS_INT, 0);
if (paperId == id)
{
setProgress(progressValue);
}
}
};
public long getPaperId() {
return paperId;
}
public void setPaperId(long paperId) {
this.paperId = paperId;
}
}
I just use it as a normal custom view in my XML Layout.
In the Adapter i set the id of my content to give the receiver the data just to setprogress if its the right content.
At the end, my problem is solved, the progress is updated without the need to call notifydatasetchanged. Yeah!