How to Save Spinner Position with Shared preferences? - java

I am making an android app that asks for the users to select a Bluetooth paired device via spinner.
When the user opens the app first time, user selects a Bluetooth paired device** from list. Then when app opens second time, I want the same Bluetooth paired device to be selected. I don't want user to select the paired device every time the app is opened. How to do that?
Spinner btPairedDevicesSpinner;
BluetoothManager mBluetoothManager;
BluetoothAdapter mBluetoothAdapter;
BluetoothDevice [] mBluetoothDeviceArray;
btPairedDevicesSpinner = findViewById(R.id.btPairedDevicesSpinner);
mGetBluetoothPairedDevice ();
btPairedDevicesSpinner.setOnItemSelectedListener(mPairedDeviceOnItemSelectedListener);
public void mGetBluetoothPairedDevice () {
Set<BluetoothDevice> mPairedDevice = mBluetoothAdapter.getBondedDevices();
mBluetoothDeviceArray = new BluetoothDevice[mPairedDevice.size()];
String [] strings = new String[mPairedDevice.size()];
int index = 0;
if (mPairedDevice.size() > 0) {
for (BluetoothDevice device : mPairedDevice) {
mBluetoothDeviceArray [index] = device;
strings [index] = device.getName();
index++;
}
}
else {
String mOnDevice = "No Device found";
mPairedDeviceArrayAdapter.add(mOnDevice);
}
ArrayAdapter<String> mArrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, strings);
btPairedDevicesSpinner.setAdapter(mArrayAdapter);
}
private final AdapterView.OnItemSelectedListener mPairedDeviceOnItemSelectedListener = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
ConnectThread mConnectThread = new ConnectThread(mBluetoothDeviceArray [i], view);
mConnectThread.start();
mBluetoothToolBar.setSubtitle("Connecting");
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
Toast.makeText(BluetoothMain.this, "Nothing is selected", Toast.LENGTH_SHORT).show();
}
};

One way that should work. Store the selected device name in shared preferences. (Create the sharedPref object somewhere else like onCreate() and do the edit in spinners onItemChanged() )
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
sharedPref.edit().putString("btDeviceName", "the name").apply();
After calling
btPairedDevicesSpinner.setAdapter(mArrayAdapter);
load the device name from shared preferences and if there is one call setSelection() on spinner
String deviceName = sharedPref.getString("btDeviceName", null);
if(deviceName != null){
btPairedDevicesSpinner.setSelection(mArrayAdapter.getPosition("deviceName "));
}

Related

java.lang.IllegalStateException: System services not available to Activities before onCreate() when creating custom-adapter

I am getting an error which says:
java.lang.IllegalStateException: System services not available to Activities before onCreate()
although every action I do are after onCreate().
I have a custom adapter which has 4 buttons. When one of the button is clicked, it ultimately calls the updateList() function which is supposed to update the list with the new details.
Here's the code:
MainActivity.java
public class MainActivity extends Activity {
static int accountsCount = 0;
static FileWorker fileWorker;
static File directory;
ListView ledgerListView;
TextView noAccountsTextView;
TextView accountHierarchy;
EditText accountName;
EditText accountLimit;
AlertDialog.Builder accountDialogBuilderChild;
AlertDialog accountDialogChild;
static ArrayList<AccountsView> ledgerList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean introDone = preferences.getBoolean("intro_done", false);
boolean howToDone = preferences.getBoolean("howto_done", false);
boolean prefFilesCreated = preferences.getBoolean("files_created", false);
if(!introDone || !howToDone) {
Intent introActivity = new Intent(this, IntroActivity.class);
startActivity(introActivity);
}
noAccountsTextView = findViewById(R.id.noAccountsTextView);
ledgerListView = findViewById(R.id.mainListView);
fileWorker = new FileWorker();
directory = getFilesDir();
if(!prefFilesCreated) {
boolean filesCreated = fileWorker.createFiles(directory);
if(filesCreated) {
SharedPreferences.Editor prefEditor = preferences.edit();
prefEditor.putBoolean("files_created", true);
prefEditor.apply();
}
}
accountsCount = fileWorker.countAccounts(directory);
setMainActivityView();
}
public void addChildAccountDialog(Context context, int pos) {
String hierarchy = ledgerList.get(pos).getAccountName();
String renewalType = ledgerList.get(pos).getRenewalType();
accountDialogBuilderChild = new AlertDialog.Builder(context);
accountDialogBuilderChild.setTitle(R.string.add_child_account_dialog_title);
accountDialogBuilderChild.setPositiveButton("Ok",
(dialogInterface, i) -> addChildAccount(hierarchy, renewalType));
accountDialogBuilderChild.setNegativeButton("Cancel",
(dialogInterface, i) -> dialogInterface.cancel());
accountDialogBuilderChild.setView(R.layout.dialog_add_child_account);
accountDialogChild = accountDialogBuilderChild.create();
accountDialogChild.show();
accountHierarchy = accountDialogChild.findViewById(R.id.accountHierarchyValueTV);
accountHierarchy.setText(hierarchy);
accountName = accountDialogChild.findViewById(R.id.accountNameDialogET);
accountLimit = accountDialogChild.findViewById(R.id.accountLimitDialogET);
}
private void addChildAccount(String hierarchy, String renewalType) {
String accName = hierarchy.concat(formatAccountName(accountName
.getText().toString()));
double accLimit = Double.parseDouble(accountLimit.getText().toString());
fileWorker.addChildAccount(directory,
accName,
renewalType,
accLimit);
setMainActivityView();
}
private void setMainActivityView() {
accountsCount = fileWorker.countAccounts(directory);
if(accountsCount <= 0) {
ledgerListView.setVisibility(View.GONE);
noAccountsTextView.setVisibility(View.VISIBLE);
} else {
updateList();
ledgerListView.setVisibility(View.VISIBLE);
noAccountsTextView.setVisibility(View.GONE);
}
}
public void updateList() {
fileWorker.sortAccounts(directory);
ledgerList = fileWorker.getAccountsList(directory);
AccountsViewAdapter ledgerAdapter = new
AccountsViewAdapter(this, ledgerList);
ledgerListView.setAdapter(ledgerAdapter);
}
public String formatAccountName(String accName) {
accName = accName.trim().toLowerCase();
accName = accName.replace(' ', '_');
accName = accName.replace('/', '_');
if(accName.charAt(0) != '/') {
accName = "/".concat(accName);
}
return accName;
}
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exit")
.setMessage("Are you sure?")
.setPositiveButton("Yes", (dialog, which) -> this.finishAffinity())
.setNegativeButton("No", null)
.show();
}
}
Here's the cutomAdapter code:
public class AccountsViewAdapter extends ArrayAdapter<AccountsView> {
TextView accountName;
TextView renewalType;
TextView limitValue;
TextView balanceValue;
Button buttonAddAccount;
Button buttonEditAccount;
Button buttonIncreaseBalance;
Button buttonDecreaseBalance;
MainActivity mainActivity;
public AccountsViewAdapter(Context context, ArrayList<AccountsView> arrayList) {
super(context, 0, arrayList);
}
public View getView(int position, View convertView, ViewGroup parent) {
View currentItemView = convertView;
if(currentItemView == null) {
currentItemView = LayoutInflater.from(getContext())
.inflate(R.layout.listview_row, parent, false);
}
AccountsView currentAccount = getItem(position);
assert currentAccount != null;
accountName = currentItemView.findViewById(R.id.accountNameValueTextView);
renewalType = currentItemView.findViewById(R.id.textViewRenewalTypeValue);
limitValue = currentItemView.findViewById(R.id.limitValueTextView);
balanceValue = currentItemView.findViewById(R.id.balanceValueTextView);
buttonAddAccount = currentItemView.findViewById(R.id.addAccountButton);
buttonEditAccount = currentItemView.findViewById(R.id.editAccountButton);
buttonIncreaseBalance = currentItemView.findViewById(R.id.increaseBalanceButton);
buttonDecreaseBalance = currentItemView.findViewById(R.id.decreaseBalanceButton);
accountName.setText(currentAccount.getAccountName());
renewalType.setText(currentAccount.getRenewalType());
limitValue.setText(currentAccount.getAmountLimit());
balanceValue.setText(currentAccount.getBalanceValue());
mainActivity = new MainActivity();
buttonAddAccount.setOnClickListener(v -> {
mainActivity.addChildAccountDialog(buttonAddAccount.getContext(), position);
});
return currentItemView;
}
}
As far as I understood, the error happens when I click on the "buttonAddAccount" button. I tried replacing the context in MainActivity with MainActivity.this, but that didn't help.
Here's the error log:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.biotstoiq.seshat, PID: 18232
java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:6715)
at android.view.LayoutInflater.from(LayoutInflater.java:299)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:216)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:210)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:196)
at org.biotstoiq.seshat.AccountsViewAdapter.<init>(AccountsViewAdapter.java:28)
at org.biotstoiq.seshat.MainActivity.updateList(MainActivity.java:179)
at org.biotstoiq.seshat.MainActivity.setMainActivityView(MainActivity.java:170)
at org.biotstoiq.seshat.MainActivity.addChildAccount(MainActivity.java:161)
at org.biotstoiq.seshat.MainActivity.lambda$addChildAccountDialog$2$org-biotstoiq-seshat-MainActivity(MainActivity.java:140)
at org.biotstoiq.seshat.MainActivity$$ExternalSyntheticLambda2.onClick(Unknown Source:6)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:201)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:230)
at android.app.ActivityThread.main(ActivityThread.java:7875)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:526)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
I/Process: Sending signal. PID: 18232 SIG: 9
The fileWorker code is not here since I didn't think it's required here.
Never instantiate an Activity with new ActivityClass. That doesn't properly initialize it. Only the Android framework can properly initialize an Activity, and you do that via an Intent.
Even if you could initialize an Activity like that, it would be wrong. You don't want to call that function on a new instance, you want to call it on the instance you're running in.
You shouldn't have any view or adapter class require a specific Activity anyway. You should use interfaces that pass handlers into the adapter. That method is far easier to test and easier to get right. Even if your code worked it would be next to impossible to unit test.

How give the application manifest permissions? How to do it programmatically on Android?

I used this Topic
I try this code but did not work :
PACKAGE_NAME = context.getApplicationContext().getPackageName();
try {
pi = context.getPackageManager().getPackageInfo(PACKAGE_NAME, PackageManager.GET_PERMISSIONS);
for (String perm : pi.requestedPermissions) {
Log.e("Foo", perm);
}
} catch (Exception e) {
}
But it could not help me. I have the application list, I want to get the permission that used on each of them.
How can I handle it?
UPDATE:
like the photo, When clicking on "دسترسی ها", I want to get the permission that used in that app.(for example in a telegram: Internet, storage, call, camera,...)
UPDATE 2:
I will share the adapter code for my problem
My Adapter:
class AppViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
AppViewHolder(View itemView, Context context, List<App> apps) {
super(itemView);
txt_show_permission = itemView.findViewById(R.id.txt_show_permission);
/*The String Buffer For Permissions*/
appNameAndPermissions = new StringBuffer();
PackageManager pm = context.getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : packages) {
Log.d(TAG, "App: " + applicationInfo.name + " Package: " + applicationInfo.packageName);
PackageInfo packageInfo = null;
try {
packageInfo = pm.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS);
appNameAndPermissions.append(packageInfo.packageName + "*******:\n");
//Get Permissions
requestedPermissions = packageInfo.requestedPermissions;
if (requestedPermissions != null) {
for (int i = 0; i < requestedPermissions.length; i++) {
Log.d(TAG, requestedPermissions[i]);
appNameAndPermissions.append(requestedPermissions[i] + "\n");
}
appNameAndPermissions.append("\n");
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
}
set On Click Listener On txt_show_permission in onBindViewHolder:
holder.txt_show_permission.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(String.valueOf(appNameAndPermissions));
}
});
Method for dialog in adapter class:
public void showDialog(String txtPermission) {
final Dialog dialog = new Dialog(context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.show_permission_dialog);
TextView txt_permission = dialog.findViewById(R.id.txt_permission);
Button btn_ok = dialog.findViewById(R.id.btn_ok);
txt_permission.setText(txtPermission);
btn_ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
You can loop through all the app names and get their permissions and store them in a String Buffer like this:
https://stackoverflow.com/a/14672557/10058326
Or since you want permissions to be shown on button click, you can add for each app the code you have tried with the proper app name in a OnButtonClickListener
Or you can extract the relevant permissions from the StringBuffer made earlier each time the button is clicked
EDIT: See these links on how to create a OnItemClickListener for the Recycler View. You can get the position of the row that was clicked and through that get the app name in that row which you can pass to another function. Then write code inside that function to get permissions for the app name passed and display it
https://antonioleiva.com/recyclerview-listener/
https://hackernoon.com/android-recyclerview-onitemclicklistener-getadapterposition-a-better-way-3c789baab4db
https://gist.github.com/riyazMuhammad/1c7b1f9fa3065aa5a46f
EDIT 2:
Instead of passing appNameAndPermissions to showDialog which contains the whole list, you need to extract permissions of a certain app from the String Buffer. Here's how:
String app_name = itemView.findViewById(R.id.app_name_text_view).getText().toString();
int indexOfApp = appNameAndPermissions.indexOf(app_name);
int indexOfLastPermission = appNameAndPermissions.indexOf("\n", indexOfApp);
String permissions = appNameAndPermissions.substring(indexOfApp, indexOfLastPermission);

Need Help Refreshing my database ListView in my app

My app layout apparently isn't a normal layout so I a having trouble setting my List Adapter to auto updated when an edit is made.
I make my edits to my database in this Java File which is controlled in its own activity and layout.
public void onClick(View view){
if (view == findViewById(R.id.addsave)) {
RecipeRepo repo = new RecipeRepo(this);
Recipe recipe = new Recipe();
if (editTextName.getText().toString().equals("")) {
editTextName.setError("Recipe name required!");
return;
} else {
recipe.name = editTextName.getText().toString();
}
if (textImagePath.getText().toString().equals("") ) {
recipe.image = ("");
}else{
recipe.image = textImagePath.getText().toString();
}
recipe.category = staticSpinner.getSelectedItem().toString();
if (editTextIngredients.getText().toString().equals("")) {
editTextIngredients.setError("Ingredient required!");
return;
} else {
recipe.ingredients = editTextIngredients.getText().toString();
}
if (editTextInstruct.getText().toString().equals("")) {
editTextIngredients.setError("Instruction required!");
return;
} else {
recipe.instructions = editTextInstruct.getText().toString();
}
recipe.cooktemp = editTextCookTemp.getText().toString();
recipe.cooktime = editTextCookTime.getText().toString();
recipe.serves = editTextServings.getText().toString();
recipe.recipe_Id = _Recipe_Id;
if (_Recipe_Id == 0) {
_Recipe_Id = repo.insert(recipe);
Toast.makeText(this, "New Recipe Added", Toast.LENGTH_SHORT).show();
finish();
it actually inserts and updates in this java file
int insert(Recipe recipe){
//Open connection to write data
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Recipe.KEY_SERVES, recipe.serves);
values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
values.put(Recipe.KEY_CATEGORY, recipe.category);
values.put(Recipe.KEY_IMAGE, recipe.image);
values.put(Recipe.KEY_NAME, recipe.name);
//Inserting Row
long recipe_Id = db.insert(Recipe.TABLE, null, values);
db.close();// Closing database connection
return (int) recipe_Id;
}
void delete(int recipe_Id){
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete(Recipe.TABLE, Recipe.KEY_ID + "=?", new String[] {String.valueOf(recipe_Id)});
db.close();
}
void update(Recipe recipe){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Recipe.KEY_SERVES, recipe.serves);
values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
values.put(Recipe.KEY_CATEGORY, recipe.category);
values.put(Recipe.KEY_IMAGE, recipe.image);
values.put(Recipe.KEY_NAME, recipe.name);
db.update(Recipe.TABLE, values, Recipe.KEY_ID + "=?", new String[]{String.valueOf(recipe.recipe_Id)});
db.close();
}
and lastly it gets put into the list view from this Java file and separate layout. Which is where my adapters are but i cannot get the notifyDataSetChanged() to work here at all... as in it wont even come up.
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
RecipeRepo repo = new RecipeRepo(this);
if (id == R.id.nav_meat) {
final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeMeat();
if(recipeList.size()!=0) {
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
String recipeId = recipe_Id.getText().toString();
Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
startActivity(objIndent);
}
});
ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
lv.setAdapter(adapter);
}else {
Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
}
} else if (id == R.id.nav_veg) {
final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeVeg();
if(recipeList.size()!=0) {
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
String recipeId = recipe_Id.getText().toString();
Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
startActivity(objIndent);
}
});
ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
lv.setAdapter(adapter);
}else {
Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
}
So any advise on setting this up to automatically update would be a huge help. I have been racking my brain over this for a couple days now looking at different examples and what not, but no setup is quite like this one which doesnt allow me to have everything in one file.
And thank you in advance.
category picking image:
Category picking Image
There are for sure more answers but this is one that might help,
Quick Example for the proposed solution
SHORT EXPLANATION
inside MainActivity
//create a public static adapter
public static ListAdapter adapter
inside onCreateView()
//Create your adapter and set it to the right ListView
ListView lv = findViewById(R.id.listView_in_xml);
adapter = new SimpleAdapter(...)
lv.setAdapter(adapter)
inside CustomAdapter which in your case I assume is SimpleAdapter
//add a public method to be called so that the Adapter updates and displays the new data
public void updateMethod(){
//update your List<Recipe> that I would guess you have calling the database again
//if needed update your getCount() return value so that it returns the number of childs in your ListView which most of the cases is just the List<Recipe>.size()
//notifyDataSetChanged()
}
inside your DB HANDLER CLASS
//in every update, add, delete or any method that requires the ListView to Update just call the created method,
MainActivity.CustomAdapter.updateMethod();
PROBLEMS
You will have to make sure the public static adapter has been initialized and is not null, or simply check whether the adapter is not null and update, because if the adapter is null that activity has not launched yet thus no need to trigger the updateMethod().
OTHER SOLUTIONS
Instead of creating a public static adapter create a public static boolean, then whenever data changes set that boolean to true from the database.
Finally, whenever you resume your activity check against that boolean and update your ListViewAdapter if needed.
MORE COMPLICATED SOLUTIONS WHICH I KNOW WORK CAUSE I USE IT
Use TaskAsyncTaskLoader which utilizes a Loader in your MainActivity and implements LoaderManager.LoaderCallbacks.
Optionally, you can make the Loader be, public static Loaderand inside your DBHandler you trigger the loader to load the data again or use any other logic you want.
Proofs of Working suggested solution,
You can Broadcast Intent from the change database file after you get the response in the onCreate() of adapter loading class
Intent intent = new Intent("key_to_identify_the_broadcast");
Bundle bundle = new Bundle();
bundle.putString("edttext", "changed");
intent.putExtra("bundle_key_for_intent", bundle);
context.sendBroadcast(intent);
and then you can receive the bundle in your fragment by using the BroadcastReceiver class
private final BroadcastReceiver mHandleMessageReceiver = new
BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle =
intent.getExtras().getBundle("bundle_key_for_intent");
if(bundle!=null){
String edttext = bundle.getString("edttext");
}
//you can call any of your methods for using this bundle for your use case
}
};
in onCreate() of your adapter adding class you need to register the broadcast receiver first otherwise this broadcast receiver will not be triggered
IntentFilter filter = new IntentFilter("key_to_identify_the_broadcast");
getActivity().getApplicationContext().
registerReceiver(mHandleMessageReceiver, filter);
Finally you can unregister the receiver to avoid any exceptions
#Override
public void onDestroy() {
try {
getActivity().getApplicationContext().
unregisterReceiver(mHandleMessageReceiver);
} catch (Exception e) {
Log.e("UnRegister Error", "> " + e.getMessage());
}
super.onDestroy();
}

How to display seekBar value and selected spinner item from Activity A to Activity B?

I have a listView in Activity A , which the value are returned from Activity B.When the list is clicked, it will intent to Activity B for edit.
Activity B
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.add_details_information);
addItemsOnSpinner();
if(getIntent().getExtras()!=null) // if has value pass from A
{
final String Project1=getIntent().getStringExtra("ReceiveProject");
final String Description1=getIntent().getStringExtra("ReceiveDescription");
final String Progress1=getIntent().getStringExtra("ReceiveProgress");
final String TimeIn1=getIntent().getStringExtra("ReceiveTimeIn");
final String TimeOut1=getIntent().getStringExtra("ReceiveTimeOut");
//project.setText(Project1);
description.setText(Description1);
//progressText.setText("Covered:")
timeIn.setText(TimeIn1);
timeOut.setText(TimeOut1);
}
save.setOnClickListener(new View.OnClickListener()
{ // return to A
#Override
public void onClick(View v)
{
Intent returnIntent=new Intent();
Project=project.getSelectedItem().toString(); // Spinner Value
Description=description.getText().toString(); //from editText
progress=seekBar.getProgress(); // From SeekBar
returnIntent.putExtra("Project",Project);
returnIntent.putExtra("Description", Description);
returnIntent.putExtra("progress", progress);
Toast.makeText(getApplicationContext(), progress+"", Toast.LENGTH_LONG).show();
returnIntent.putExtra("TimeIn", TimeIn);
returnIntent.putExtra("TimeOut",TimeOut);
setResult(Activity.RESULT_OK,returnIntent);
finish();
}
});
public void addItemsOnSpinner()
{
project=(Spinner)findViewById(R.id.SpinnerProject);
List<String> list = new ArrayList<String>();
list.add("TRN-XXX-XXX");
list.add("Pro-XXX-XXX);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.spinner_item, list);
//adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
project.setAdapter(adapter);
}
Activity A
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { // if listView is clicked
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
mClickedPosition = position;
Intent i = new Intent(getApplication(), Add_Details_Information.class);
i.putExtra("ReceiveProject", ReceiveProject);
i.putExtra("ReceiveDescription", ReceiveDescription);
i.putExtra("ReceiveProgress", ReceiveProgress);
i.putExtra("ReceiveTimeIn", ReceiveTimeIn);
i.putExtra("ReceiveTimeOut", ReceiveTimeOut);
startActivityForResult(i,PROJECT_REQUEST_CODE);
}
});
}
I know that we can use setText to display the passed value from A to B for editText, but how about the spinner and seekBar value ?
This is the listView in Activity A. Value are returned from Activity B.
When listView is clicked, it will goes to B again to edit.
So how can I make the spinner in B display Pro-XXX-XXX and the seekBar goes to 48 ? Any idea or suggestion ? Thanks a lot
Edited
After used the answer from #Clairvoyant, now I get this (for spinner value).
Activity A
There are 4 list in Activity A.
Assume first list is clicked.
Everything works fine just the spinner(Project/Service/Training) display wrong value. It display the spinner value from last list(PRO-SKM-D5) instead of itself(Pro-XXX-XXX)
First Step: Make your addItemsOnSpinner like as below:
public void addItemsOnSpinner(String value)
{
int position = 0;
project=(Spinner)findViewById(R.id.SpinnerProject);
List<String> list = new ArrayList<String>();
list.add(position,"TRN-XXX-XXX");
list.add("Pro-XXX-XXX");
for(int i=0; i<list.size() ; i++){
if(list.get(i).equalsIgnoreCase(value)){
position = i;
break;
}
}
ArrayAdapter<String> adapter = new ArrayAdapter<String> (getApplicationContext(),R.layout.spinner_item, list);
//adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
project.setAdapter(adapter);
project.setSelection(position);
}
Second Step: call the above method when you are assigning value to the variable you have to show in spinner here for eg: project1 is the string value which you want to show in spinner then call the method as follows:
final String Project1=getIntent().getStringExtra("ReceiveProject");
addItemsOnSpinner(Project1);
Use SharedPreferences. Next time, googling helps.
Get SharedPreferences
SharedPreferences prefs = getDefaultSharedPreferences(context);
Read preferences:
String key = "test1_string_pref";
String default = "returned_if_not_defined";
String test1 = prefs.getString(key, default);
To edit and save preferences
SharedPreferences.Edtior editor = prefs.edit(); //Get SharedPref Editor
editor.putString(key, "My String");
editor.commit();
Shorter way to write
prefs.edit().putString(key, "Value").commit();
Additional info for SharedPreferences: JavaDoc and Android Developers Article

How to pass string array to AlertDialog builder.setItems()

I am using Alert Dialog builder in order to visualize the paired bluetooth devices. I want to pass a sstring array to the setItems() method in order to create the list with the devices. setItems() gets CharSequence[] and a listener. When i pass the string array it fails. How can i fix it? Here is the code:
public void showPairedDevices() {
String[] pairedDevicesArray = new String[100];
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevicesSet = bluetoothAdapter
.getBondedDevices();
if (pairedDevicesSet.size() > 0) {
int i = 0;
for (BluetoothDevice device : pairedDevicesSet) {
pairedDevicesArray[i] = device.getName();
i++;
}
connectDialog = new AlertDialog.Builder(context);
connectDialog.setTitle("Paired devices");
connectDialog.setItems(pairedDevicesArray, connectDialogClickListener);
connectDialog.show();
} else {
Toast.makeText(context, "No paired devices!", Toast.LENGTH_SHORT)
.show();
}
}
private OnClickListener connectDialogClickListener = new OnClickListener() {
#Override
public void onClick(DialogInterface connectDialog, int button) {
connectDialog.dismiss();
}
};
Your issue stems from the fact that you're starting with a String array that is too big. When you initialize an array of objects, every space is by default null. With that in mind, what you should know is that when you feed an array that is of length 100 to setItem(), it is going to check every index, and if it finds a null it will throw an error. Here is a proposed solution:
public void showPairedDevices() {
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevicesSet = bluetoothAdapter
.getBondedDevices();
if (pairedDevicesSet.size() > 0) {
// This will set the size of the array to exactly how many you need
String[] pairedDevicesArray = new String[pairdDevicesSet.size()];
int i = 0;
for (BluetoothDevice device : pairedDevicesSet) {
pairedDevicesArray[i] = device.getName();
i++;
}
// ...
}

Categories