How can I set my app to behave in such a way that when user arrives on my app for the first time a page appears for them to choose their status?
E.g
Student
Teacher
What I want is for two buttons to appear on that first screen they will see on the app.
So if a user clicks Student, each time he/she opens that app he will always be directed to an activity I designed for just students e.g student_activity layout.
But if the student choose Teacher, each time the app runs it will take the user to teacher_activity layout.
I will be so much thankful to anyone that can provide me with a good to set this on my app.
Plenty thanks as you look into it.
you need to use sharedPrefrences to store the user choice and then check the saved choice when your application is launched
create a SharedInfo class :
public class SharedInformation {
private Context context;
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
public SharedInfo(Context c){
context = c;
sharedPreferences =context.getSharedPreferences("login.conf", Context.MODE_PRIVATE);
editor=sharedPreferences.edit();
}
public void setusertype(String type){
editor.putString("type",type);
editor.apply();
editor.commit();
}
public String getusertype(){
return sharedPreferences.getString("type","");
}
public void clearinfo(){
editor.clear();
editor.commit();
}
}
In your main/welcome activity:
SharedInfo sharedinfo = new SharedInfo(this);
if(sharedinfo.getusertype().isEmpty()){ //do nothing let the user pick a choice}
if(sharedinfo.getusertype().equals("student"){
//make an intent to send to student activity
}
if(sharedinfo.getusertype().equals("teacher"){
//make an intent to send to teacher activity
}
//etc
When the user picks a choice for the first time make sure to save it in your SharedInfo class like that :
sharedinfo.setusertype("yourtype");
Related
I am trying to print the current step being executed in Cucumber. I am using a custom formatter to print the step definition. However, I also want to print the current adverb (Given, When, Then, And...) that is being executed. I might be missing something as well, is it possible in Cucumber? Here is my code:
Formatter:
public class MyCucumberFormatter implements ConcurrentEventListener {
#Override
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, runStartedHandler);
}
private EventHandler<TestStepStarted> runStartedHandler = new EventHandler<TestStepStarted>() {
#Override
public void receive(TestStepStarted event) {
startReport(event);
}
};
private void startReport(TestStepStarted event) {
if (!(event.testStep instanceof PickleStepTestStep)) {
return;
}
PickleStepTestStep testStep = (PickleStepTestStep) event.testStep;
log("Step: " + testStep.getStepText());
}
}
Example scenario:
Scenario: Test user life cycle: create user, activate and delete
Given A valid admin logs in
When Admin creates new user
And User is activated
Then User should successfully login
Right now, it prints as:
A valid admin logs in
Admin creates new user
User is activated
User should successfully login
I want it to print as:
Given A valid admin logs in
When Admin creates new user
And User is activated
Then User should successfully login
You can't do this in v4.x yet but you can do this in v5.0.0-RC1 by going through pickleStepTestStep.getStep().getKeyWord()
I am trying to sign out a user once a process is completed, I tried using the PXAccess or the PXAccessInfo classes in order to do so but did not manage to find a correct way in logging out a user. Are there any other means in signing out a user which I might have glossed over?
I adapted the standard SignOut code so it can be run from a graph extension instead of a Aspx.cs web page. It is equivalent to this SignOut menu item:
In this example I put the code in SOOrderEntry Initialize override so it signs out the current user as soon as you navigate to the SalesOrderEntry graph. You can put it in an Action event handler but I haven't tested it in a PXLongOperation context which runs in a separate thread context:
public class SOOrderEntry_Extension:PXGraphExtension<SOOrderEntry>
{
public override void Initialize()
{
System.Web.UI.Page page = System.Web.HttpContext.Current.Handler as System.Web.UI.Page;
if (page != null)
{
PX.Data.PXLogin.LogoutUser(PX.Data.PXAccess.GetUserName(), page.Session.SessionID);
PX.Common.PXContext.Session.SetString("UserLogin", string.Empty);
string absoluteLoginUrl = PX.Export.Authentication.AuthenticationManagerModule.Instance.SignOut();
page.Session.Abandon();
PX.Data.Auth.ExternalAuthHelper.SignOut(System.Web.HttpContext.Current, absoluteLoginUrl);
PX.Export.Authentication.FormsAuthenticationModule.
RedirectToLoginPage(PX.Data.Auth.ExternalAuthHelper.SILENT_LOGIN + "=None", true);
}
}
}
We're using the Run Project Billing screen to create records in AR / Invoice and Memo.
In the Invoice & Memo screen, we need the process to populate the header Customer Ord. number, along with a user field that has been added to the grid section on the 'Document Details' tab. At the moment, the process is not doing this.
I'd like to intercept the processing action on the screen using a technique I'm familiar with, namely using an 'AddHandler':
[PXOverride]
protected virtual IEnumerable Items (PXAdapter adapter)
{
PXGraph.InstanceCreated.AddHandler<BillingProcess>((graph) =>
{
graph.RowInserting.AddHandler<BillingProcess.ProjectsList>((sender, e) =>
{
//Custom logic goes here
});
});
return Base.action.Press(adapter);
}
I see no Base.Actions that remotely resembles 'Bill' or 'Bill All'.
This is obviously not exactly the code I need, but I would think this is the general place to start.
After reviewing the source business logic, I don't see any 'Bill' or 'Bill All' Actions - or any 'Actions' at all (baffling). I see an IEnumerable method called 'items', so that's what I started with above.
Is this the correct way to go about this?
Update: 2/14/2017
Using the answer provided re: the overridden method InsertTransaction(...) I've tried to set our ARTran user field (which is required) using the following logic:
PMProject pmproj = PXSelect<PMProject, Where<PMProject.contractID, Equal<Required<PMProject.contractID>>>>.Select(Base, tran.ProjectID);
if (pmproj == null) return;
PMProjectExt pmprojext = PXCache<PMProject>.GetExtension<PMProjectExt>(pmproj);
if (pmprojext == null) return;
ARTranExt tranext = PXCache<ARTran>.GetExtension<ARTranExt>(tran);
if (tranext == null) return;
tranext.UsrContractID = pmprojext.UsrContractID;
Even though this sets the user field to the correct value, it still gives me an error that the required field is empty when the process finishes. My limited knowledge prevents me from understanding why.
On the Run Project Billing screen, captions of Process and Process All buttons were changed to Bill and Bill All respectively in BLC constructor.
Process delegate is set for Items data view within the BillingFilter_RowSelected handler:
public class BillingProcess : PXGraph<BillingProcess>
{
...
public BillingProcess()
{
Items.SetProcessCaption(PM.Messages.ProcBill);
Items.SetProcessAllCaption(PM.Messages.ProcBillAll);
}
...
protected virtual void BillingFilter_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
BillingFilter filter = Filter.Current;
Items.SetProcessDelegate<PMBillEngine>(
delegate (PMBillEngine engine, ProjectsList item)
{
if (!engine.Bill(item.ProjectID, filter.InvoiceDate, filter.InvFinPeriodID))
{
throw new PXSetPropertyException(Warnings.NothingToBill, PXErrorLevel.RowWarning);
}
});
}
...
}
As code snippet above confirms, all records in the AR Invoice and Memos screen are created by instance of the PMBillEngine class. Below is code snippet showing how to override InsertNewInvoiceDocument and InsertTransaction methods within the PMBillEngine BLC extension:
public class PMBillEngineExt : PXGraphExtension<PMBillEngine>
{
public delegate ARInvoice InsertNewInvoiceDocumentDel(string finPeriod, string docType, Customer customer,
PMProject project, DateTime billingDate, string docDesc);
[PXOverride]
public ARInvoice InsertNewInvoiceDocument(string finPeriod, string docType, Customer customer, PMProject project,
DateTime billingDate, string docDesc, InsertNewInvoiceDocumentDel del)
{
var result = del(finPeriod, docType, customer, project, billingDate, docDesc);
// custom logic goes here
return result;
}
[PXOverride]
public void InsertTransaction(ARTran tran, string subCD, string note, Guid[] files)
{
// the system will automatically invoke base method prior to the customized one
// custom logic goes here
}
}
Run Project Billing process invokes InsertNewInvoiceDocument method to create new record on the AR Invoice and Memos screen and InsertTransaction method to add new invoice transaction.
One important thing to mention: overridden InsertNewInvoiceDocument and InsertTransaction methods will be invoked when a user launches Run Project Billing operation either from the processing Run Project Billing screen or from the data entry Projects screen.
For more information on how to override virtual BLC methods, see Help -> Customization -> Customizing Business Logic -> Graph -> To Override a Virtual Method available in every Acumatica ERP 6.1 website
I'm using Windows Azure Mobile Services to store and retrieve data in my Windows Phone 8 app. This is a bit of a complicated issue so I will do my best to explain it.
Firstly I'm using raw push notifications to receive a message and when it receives the message it updates a listbox in my app. When I open my app, navigate to the page with the ListBox and receive a push notification the ListBox updates fine. If I press back, then navigate to the same page with the ListBox, the push notification is received, the code to update the ListBox executes with no errors yet the ListBox doesn't update. I have checked that the same code runs using the OnNavigatedTo handler in both scenarios, but it seems like the ListBox does not bind correctly in the second instance when I press back and then re-navigate to the same page. Here are some code snippets:
MobileServiceCollection declarations:
public class TodoItem
{
public int Id { get; set; }
[JsonProperty(PropertyName = "text")]
public string Text { get; set; }
}
private MobileServiceCollection<ToDoItem, ToDoItem> TodoItems;
private IMobileServiceTable<TodoItem> todoTable = App.MobileService.GetTable<TodoItem>();
Push Notification Received Handler:
void PushChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
{
string message;
using (System.IO.StreamReader reader = new System.IO.StreamReader(e.Notification.Body))
{
message = reader.ReadToEnd();
}
Dispatcher.BeginInvoke(() =>
{
var todoItem = new TodoItem
{
Text = message,
};
ToDoItems.Add(todoItem);
}
);
}
I have tried using:
ListItems.UpdateLayout();
and
ListItems.ItemsSource = null;
ListItems.ItemsSource = ToDoItems;
before and after the code in the above procedure that adds the ToDoItem but it didn't help.
The following procedure is called in my OnNavigatedTo event handler, and refreshes the Listbox and assigns ToDoItems as the items source:
private async void RefreshTodoItems()
{
try
{
ToDoItems = await todoTable
.ToCollectionAsync();
}
catch (MobileServiceInvalidOperationException e)
{
MessageBox.Show(e.Message, "Error loading items", MessageBoxButton.OK);
}
ListItems.ItemsSource = ToDoItems;
}
The above procedure is async but I have made sure it completes before receiving any notifications. Even so, as mentioned above when I open the app, navigate to the page that shows the ListBox it updates fine. When I press back, navigate to the same page again, it doesn't work. When I back out of the app, re-open it, navigate to the page with the ListBox, it works again, and then fails if I press back and re-open the page. So it seems the ListBox is not binding to ToDoItems correctly when I press back and navigate to the same page.
Any help appreciated. Thanks.
Can you modify your approach a bit to use Data Binding and the MVVM model to bind your model to your view.
It might look like a bit of effort initially but will save you a lot of debugging hours later on.
Just follow the below steps
Create a new class that implements INotifyPropertyChanged
Add the below method implementation
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Add public ObservableCollection<TodoItem> TodoItems{ get; private set; } and initialize it in the constructor.
Every PhoneApplicationPage has a DataContext member. Assing it to a singleton instance of the above class that you create.
In the XAML, add the property ItemsSource="{Binding TodoItems}" to the list.
In the DataTemplate of the list use ItemsSource="{Binding Text}" for the control you wish to display this value on. ( e.g. TextBlock )
Now whenever you add elements to the collection, it will be reflected in the UI, and vice-versa.
I could use a little help. I got this program to work right then I found out I had to use the MVC design. It seems pretty simple but, my little toy program won't display my forms. HELP!! See the below snipets:
PART OF MIDLET
public MileageMidlet()
{
// First get a blank user form
form = new Form("Bradford Gas Mileage Calculator");
startPage = new StartPageView();
inputScreen = new InputScreen();
calculateMileage = new CalculateMileage();
startCmd = new Command ("Start",Command.SCREEN,5);
clearCmd = new Command ("Clear",Command.SCREEN,1);
enterCmd = new Command ("Enter",Command.SCREEN,1);
exitCmd = new Command("Exit", Command.EXIT, 1);
// Set up event handlers to process user commands
form.setCommandListener(this);
}
public void startApp() {
startPage.createView(form);
form.addCommand(startCmd);
form.addCommand(exitCmd);
// Display initial form
Display.getDisplay(this).setCurrent(form);
}
START PAGE VIEW CLASS
import javax.microedition.lcdui.*;
public class StartPageView
{
StringItem strgItm, strgItm2;
private Command startCmd, exitCmd;
public StartPageView()
{
}
public void createView(Form form)
{
// First get a blank user form
form.deleteAll();
form = new Form("Bradford Gas Mileage Calculator");
strgItm = new StringItem ("","Welcome to the Bradford Mobile Gas Mileage Calculator!");
strgItm2 = new StringItem ("","To obtain you gas mileage please click the start button.");
form.append(strgItm);
form.append(strgItm2);
}
I got nothing! Really literally a blue screen.
}
The issue has nothing to do with MIDP or J2ME. The problem is of the semantics of how arguments are passed to methods.
It;s important to remember that arguments to method are passed by value in Java. The consequence is that when an object that is passed to a method, a copy of that reference is passed. Any changes to the reference of the object in the method does not have any affect outside of it.
Please see this article for more information.
So in your code,
form.deleteAll();
form = new Form("Bradford Gas Mileage Calculator");
Comment the above two lines. Everything should be fine.