Propose again my question. Sorry for the repetition.
I have a ListView where there are all the applications installed on the device. At the click on the item, part of the uninstall. So far everything works fine, the problem is that once the application is uninstalled, then it is no longer on the device, it remains in the list. Obviously this is not good and therefore I wrote this code to try to remove it once it has been uninstalled.
int position;
myListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
int requestCode = 1;
app = appInfoArrayList.get(position);
Uri packageUri = Uri.parse("package:"+app.packagename);
//In theory i should put
//this.position=position;
//But Eclipse says "position cannot be resolved or is not a field"
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageUri);
startActivityForResult(uninstallIntent, requestCode);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
String msg = "MyApp: ";
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1)
{
try {
packageInfo = getPackageManager().getApplicationInfo(app.packagename, 0);
}
catch (PackageManager.NameNotFoundException e) {
Log.v("Catch",msg );
appInfoArrayList.remove(position);
adapter.notifyDataSetChanged();
}
}
else {
}
Log.v(msg, String.valueOf(resultCode)+", "+String.valueOf(requestCode));
}
In the LogCat i read: MyApp: Catch 0 (resultCode) , 1 (requestCode) So this means that enters correctly in the catch, but despite this, even if the application has been uninstalled is still on the list. Ideas on how I can fix this? Thanks in advance.
Adapter declaration
AppAdapter adapter;
The position in appInfoArrayList.remove(position); is uninitialized make sure that you assign value to it.
You should redraw the list, call the adapter.notifyDataSetChanged() after renewing the adapter data source, this should solve the problem if you use the same ArrayList to store and to show the data
You are using this on exception
appInfoArrayList.remove(position);
adapter.notifyDataSetChanged();
This should get called correctly to reflect the changes , check the data
Related
Could someone help me change my IF statement to take in the detail that is inside the list view rather than the position of the listview? The list view will display three details which can be seen in the image below.
listViewSaves.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (position == 0) {
Intent myIntent = new Intent(MainActivity.this, Game_500.class);
MainActivity.this.startActivity(myIntent);
}
if (position == 1) {
Intent myIntent = new Intent(MainActivity.this, Game_1000.class);
MainActivity.this.startActivity(myIntent);
}
if (position == 2) {
Toast.makeText(getApplicationContext(), "Your toast message3.",
Toast.LENGTH_SHORT).show();
}
}
});
Check below image for an example of the list view
Check the below image for how the list view is populated
I want the listview to open up their own activity. For example IF the list view shows (Gaming) and (Under 500) - open Game_500.class.
If the list view has (Gaming) and (Under 1000) -open Game_1000.class.
The list view is populated by asking the users to select from 2 choices. Type of system - Gaming or Personal Use and the price of the system - Under 500 or Under 1000.
Use this code for ListView setOnItemClickListener. Here you have to take RigSaves object from List with position and check if it meet your criteria.
listViewSaves.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
RigSaves rigSaves = savesList.get(position);
// Gaming option
if( rigSaves.getRigType().equals("Gaming") && rigSaves.getRigPrice().equals("Under 500") ){
Intent myIntent = new Intent(MainActivity.this, Game_500.class);
startActivity(myIntent);
}
if( rigSaves.getRigType().equals("Gaming") && rigSaves.getRigPrice().equals("Under 1000") ){
Intent myIntent = new Intent(MainActivity.this, Game_1000.class);
startActivity(myIntent);
}
// personal option
if( rigSaves.getRigType().equals("Personal Use") && rigSaves.getRigPrice().equals("Under 500") ){
// start activity you want to start
}
if( rigSaves.getRigType().equals("Personal Use") && rigSaves.getRigPrice().equals("Under 1000") ){
// start activity you want to start
}
}
});
Hope it helps you. And let me know if you faced any problem
Try this out :
When calling Intent, you should use the class's name as string with package name. So if your class is called Game_1000 and is in the package mypackage.tests, then you should use:
Intent myIntent = new Intent(MainActivity.this, Class.forName("mypackage.tests.Game_1000"));
MainActivity.this.startActivity(myIntent);
I need to delete an item permanently from ListView and then from database. I have a DatabaseHandler.java class, which has the delete function as:
// Deleting single contact, in DatabaseHandler.java class
public void deleteContact(Contact contact) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
new String[] { String.valueOf(contact.getID()) });
db.close();
}
Then I have a FriendList.java class, when the user's friends are displayed as an item in ListView. When I long press on an item, then I get the option of "Delete" and "Cancel" in Dialog Box. Now, when I click on delete, the item is deleted from the ListView, but, not from the database. How can I delete it from database as well?
The code for getting the option of "Delete" and "Cancel"
listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long id) {
// TODO Auto-generated method stub
Intent i = new Intent(FriendList.this, Delete_Confirm.class).addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
//I am sending position of listitem in putExtra below//
i.putExtra("position", position);
startActivityForResult(i,CONFIRM);
item2 = (String) arg0.getItemAtPosition(position);
//Toast.makeText(FriendList.this, "Clicked"+item2, Toast.LENGTH_SHORT).show();
int l = item2.length();
c=0;
for(int j=0; j<=l; j++){
if(item2.charAt(j) != '9' || item2.charAt(j+1) != '1'){
c++;
}
else {
//Do nothing
break;
}
num = item2.substring(c, l);
}
Toast.makeText(FriendList.this, "Clicked: "+num, Toast.LENGTH_SHORT).show();
return true;
}
});
The corresponding code for onActivityResult is as follows:
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (CONFIRM) :
if(resultCode==RESULT_OK){
int posi = data.getIntExtra("position",0);
Log.d("msg","position is " + posi);
Log.d("msg","Do we reach here?");
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
//db.deleteContact(posi);
list.remove(posi);
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
break;
}}
Please suggest how can I delete it from database as well. Any help would be highly appreciated.
EDIT:
On uncommenting db.deleteContact(posi), I get the following error:
The method deleteContact(Contact) in the type DatabaseHandler is not applicable for the arguments (int)
Note that the function deleteContact has contact variable of the type Contact.
Its a compilation error.
You need to pass a Contact object to the method, not an integer.
When you delete.... Try Deleting first from database then from ListView..
example:
db.deleteContact(list.get(posi)); // this will get string
list.remove(posi);
DatabaseHandler class.......
public void deleteContact(String name){
Log.d("Name:",""+ name);
db.delete(TABLE_CONTACTS, KEY_NAME + " = ?", new String[] { name });
}
You can delete from database first then from ListView. And suggest Iterator to remove list element.
I think the problem is that position is not the corresponding id in the database. A possible solution would be to add a tag with the database id of the contact you have in this listitem. And when you remove it you get the tag with the id and delete the item from the database.
Edit (added clarification):
I would add in your listviewadapter something like:
yourcontactview.setTag(contact.getId());
in which you add to your view a tag with the database id of the corresponding contact.
Then where you delete the contact I would get the contact you want to delete with something like this:
Contact deletecontact = db.getContact(view.getTag());
db.deleteContact(deletecontact);
Of course you could change your
deleteContact(Contact contact) to a method in which you give the id instead of the contactobject.
This should hopefully work.
I have a fragment in which I have a RecyclerView:
public class AlarmListFragment extends Fragment{
public AlarmListAdapter alarmListAdapter;
RecyclerView recyclerViewAlarms;
public AlarmListFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_alarm_list, container, false);
recyclerViewAlarms = (RecyclerView) rootView.findViewById(R.id.fragment_alarm_list_card_list);
recyclerViewAlarms.setHasFixedSize(true); // performance!
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
recyclerViewAlarms.setLayoutManager(llm);
alarmListAdapter = new AlarmListAdapter(getActivity());
recyclerViewAlarms.setAdapter(alarmListAdapter);
return rootView;
}
It uses the following Adapter:
public class AlarmListAdapter extends RecyclerView.Adapter<AlarmListViewHolder> {
private List<AlarmModel> alarmModelDataSet;
private Context context;
public AlarmListAdapter(Context context) {
this.alarmModelDataSet = AlarmModel.listAll(AlarmModel.class);
this.context = context;
}
#Override
public AlarmListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.alarm_list_card, parent, false);
return new AlarmListViewHolder(view);
}
#Override
public int getItemCount() {
return (int) AlarmModel.count(AlarmModel.class, null, null);
}
#Override
public void onBindViewHolder(AlarmListViewHolder holder, int position) {
// todo wait here until alarmModel is added to DataSet
AlarmModel alarmModel = alarmModelDataSet.get(position);
*** update GUI stuff ***
if (alarmModel.isEnabled()) {
*** update GUI stuff ***
}
if (alarmModel.isRepeatWeekly()) {
*** update GUI stuff ***
} else {
*** update GUI stuff ***
}
if (!alarmModel.isEnabled()){
*** update GUI stuff ***
}
}
public List<AlarmModel> getDataSet(){
return alarmModelDataSet;
}
public int getIndex(AlarmModel alarmModel){
for (AlarmModel _item : alarmModelDataSet){
if (_item.getId().equals(alarmModel.getId())){
return alarmModelDataSet.indexOf(_item);
}
}
return -1;
}
public void addOrUpdateAlarm(AlarmModel alarmModel){
int position = getIndex(alarmModel);
if (position >= 0) {
updateAlarm(alarmModel, position);
} else {
addAlarm(alarmModel);
}
}
private void addAlarm(AlarmModel alarmModel){
alarmModelDataSet.add(alarmModel);
notifyItemInserted(alarmModelDataSet.size() - 1);
}
private void updateAlarm(AlarmModel alarmModel, int position){
alarmModelDataSet.set(getIndex(alarmModel), alarmModel);
notifyItemChanged(position);
}
public void deleteAlarm(AlarmModel alarmModel) {
alarmModel.setIsEnabled(false);
AlarmManagerBroadcastReceiver.setAlarms(context);
int position = getIndex(alarmModel);
alarmModelDataSet.remove(position); // deletes out of class internal List
notifyItemRemoved(position); // notifies list fragment of deletion
}
public void enableOrDisableAlarm(int position){
AlarmModel alarmModel = alarmModelDataSet.get(position);
alarmModel.setIsEnabled(!alarmModel.isEnabled());
notifyItemChanged(position);
}
Every alarmModel is saved in a database which is working fine thus I removed the code about the database.
The fragment from the first code snippet uses startActivityForResult to open up an activity that allows the creation of a new alarm that is stored in another alarmModel. This new alarmModel is saved to the data base and its ID is returned to my fragment by this code
Intent intent = new Intent();
intent.putExtra("id", alarmDetails.getId());
intent.putExtra("delete", false);
setResult(RESULT_OK, intent);
supportFinishAfterTransition();
This result is received by the onActivityResult method of the fragment:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_ADD_ALARM_ID) {
long id = data.getLongExtra("id", -7777);
if (data.getBooleanExtra("delete", false)) { // delete
alarmListAdapter.deleteAlarm(AlarmModel.findById(AlarmModel.class, id));
} else { // add or update
alarmListAdapter.addOrUpdateAlarm(AlarmModel.findById(AlarmModel.class, id));
}
}
}
After all this code I finally am able to describe my problem:
Before the code even reaches the addOrUpdate method, the adapter's onBindViewHolder method is called and produces an IndexOutOfBoundsException because AlarmModel alarmModel = alarmModelDataSet.get(position); the just added alarmModel wants to get drawn but is not yet added to the DataSet.
Everything works fine (although the app becomes pretty slow) when the RecyclerView has ~10+ items since onBindViewHolder is called for every other item first and after calculating 9 other items the addOrUpdate method has finished.
Is there a fatal mistake I made or a method I did not find yet, which could help me? I thought about using two threads and letting one wait until the other one has finished but am unsure how to do that since I allready know that you should never block the Ui-Thread.
Edit 1
In an attempt to make the add, update and delete method in the adapter static I removed the List alarmModelDataSetcompletely and queried the data base every time instead. Although my initial plan did not work out, I noticed that it solved my problem by making the methods so slow that everything worked fine again. But since this is not a real solution but simply bad coding that works slowly I am not really satisfied with it...
Thanks to everybody reading this long question/problem
Tafelbomber
Hi in fragment I want to pick a phone number from contacts and inset it into EditText
but its not working in fragment I use it in activity and it works. Please could you help me how I should change it< thanks
public class Encrypt extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.encrypt, null);
phoneNumberDisplay = (EditText) v.findViewById(R.id.editTextPhoneNumber);
contactsButton=(Button)v.findViewById(R.id.buttonContacts);
contactsButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v==contactsButton){
Intent intent=new Intent(Intent.ACTION_PICK,Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri ur = data.getData();
Cursor c = managedQuery(ur, null, null, null, null);
if (c.moveToFirst()) {
String s = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phoneNumberDisplay.setText(s);
}
}
}
return v;
}
errors: RESULT_OK cannot be resolved to a variable
The method managedQuery(Uri, null, null, null, null) is undefined for the type new
View.OnClickListener(){}
Ok, you have a parenthesis that is not well placed. I suppose you want `onActivityResult to be in the click listener.
contactsButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v==contactsButton){
Intent intent=new Intent(Intent.ACTION_PICK,Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
}
}
});
// ^^
// This parenthesis should not be here
Remove the parenthesis and the semi-colon, and add them here:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri ur = data.getData();
Cursor c = managedQuery(ur, null, null, null, null);
if (c.moveToFirst()) {
String s = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phoneNumberDisplay.setText(s);
}
}
});
// ^^
// Here, so that it is in the event listener
Note: since I fixed the indentation in your post I saw this error. Next time, try to always indent your code correctly, so that you will see that kind of errors (and that's also why I dislike K&R brace style).
Update:
It is Activity.RESULT_OK, not a raw RESULT_OK.
For managedQuery: see this question.
For getContentManager: see here.
For accessing the contacts form your phone, make sure that you added the android.permission.READ_CONTACTS Permission in manifest file..
There could be two possible reasons to this.
Call your statrtActivityForResults using Activity's reference, like
getActivity().startActivityForResult(intent, 1);
Calling super.onActivityResult(requestCode, resultCode, data) in you onActivityResult() as #marcin_j also pointed.
Try either or both of them. See which one works for you.
Here's a link.
You are trying to return value when onActivityResult is void return function, you need to implement your logic without returning any value
public String getPath(Uri uri) {
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Activity ac =new Activity();
Cursor cursor =ac.managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
// this is our fallback here
return uri.getPath();
}
I have scoured SE and google and found what I thought were decent examples of how to implement putExtra() in tandem with getStringExtra().
The trouble I seem to be unable to resolve is that my putExtra data never appears to be getting retrieved from my getStringExtra call in the target activity.
I've tried numerous SE examples where others have asked this question countless times and yet it never seems to get me closer to a working base to expand on.
My primary activity's put is as follows;
(First, I tried this with no luck)
// Click handler for group list items
lvGroups.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
int gid = groupIds.get(arg2);
Intent intent = new Intent(RadSMS_Activity.this, RadSMS_CreateGroup.class);
intent.putExtra("SELECTED_GROUP_ID", gid);
startActivity(intent);
finish();
}
});
(Then, I tried this. Also with no luck.)
// Click handler for group list items
lvGroups.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
int gid = groupIds.get(arg2);
Intent target = new Intent();
target.putExtra("SELECTED_GROUP_ID", gid);
Intent intent = new Intent(RadSMS_Activity.this, RadSMS_CreateGroup.class);
startActivity(intent);
finish();
}
});
My target activity that I want to extract the value from is the following;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.creategroup);
String strGID = getIntent().getStringExtra("SELECTED_GROUP_ID");
selectedGID = new Long(strGID);
// ... additional code would be here
}
Function truncated for brevity's sake.
So, according to everything I've seen so far, it appears I'm doing it right, but when I put a breakpoint at the line where selectedGID gets assigned its value, strGID is always null. This is really beginning to make me crazy.
Can anyone please tell me if I have done something incorrect?
gid is an int.
You are putting an int.
You appear to be trying to retrieve a string.
Consider:
int gid= getIntent().getIntExtra("SELECTED_GROUP_ID",-1);
You are putting an integer value while getting it as a string. It will always return null. Use intent.getExtras().getInt() instead of intent.getStringExtra().