@@ -9,7 +9,7 @@ ms.service: active-directory
9
9
ms.subservice : develop
10
10
ms.topic : tutorial
11
11
ms.workload : identity
12
- ms.date : 03/29 /2023
12
+ ms.date : 04/04 /2023
13
13
ms.author : henrymbugua
14
14
ms.reviewer : brandwe
15
15
ms.custom : aaddev, identityplatformtop40, has-adal-ref
@@ -44,8 +44,6 @@ The app in this tutorial will sign in users and get data on their behalf. This d
44
44
45
45
This sample uses the Microsoft Authentication Library (MSAL) for Android to implement Authentication: [ com.microsoft.identity.client] ( https://javadoc.io/doc/com.microsoft.identity.client/msal ) .
46
46
47
- MSAL will automatically renew tokens, deliver single sign-on (SSO) between other apps on the device, and manage the Account(s).
48
-
49
47
## Create a project
50
48
51
49
Follow these steps to create a new project if you don't already have an Android application.
@@ -111,7 +109,7 @@ Follow these steps to create a new project if you don't already have an Android
111
109
112
110
As this tutorial only demonstrates how to configure an app in Single Account mode, see [ single vs. multiple account mode] ( ./single-multi-account.md ) and [ configuring your app] ( ./msal-configuration.md ) for more information
113
111
114
- 1 . In ** app** > ** src** > ** main** > ** AndroidManifest.xml** , add the ` BrowserTabActivity ` activity after the application body . This entry allows Azure AD to call back to your application after it completes the authentication:
112
+ 1 . In ** app** > ** src** > ** main** > ** AndroidManifest.xml** , add the ` BrowserTabActivity ` activity as a child of the ` < application> ` element . This entry allows Azure AD to call back to your application after it completes the authentication:
115
113
116
114
``` xml
117
115
<!-- Intent filter to capture System Browser or Authenticator calling back to our app after sign-in-->
@@ -650,47 +648,47 @@ Follow these steps to create a new project if you don't already have an Android
650
648
651
649
``` java
652
650
package com.azuresamples.msalandroidapp ;
653
-
651
+
654
652
import android.os.Bundle ;
655
-
653
+
656
654
import androidx.annotation.NonNull ;
657
655
import androidx.appcompat.app.ActionBarDrawerToggle ;
658
656
import androidx.appcompat.app.AppCompatActivity ;
659
657
import androidx.appcompat.widget.Toolbar ;
660
658
import androidx.constraintlayout.widget.ConstraintLayout ;
661
659
import androidx.core.view.GravityCompat ;
662
-
660
+
663
661
import android.view.MenuItem ;
664
662
import android.view.View ;
665
-
663
+
666
664
import androidx.drawerlayout.widget.DrawerLayout ;
667
665
import androidx.fragment.app.Fragment ;
668
666
import androidx.fragment.app.FragmentTransaction ;
669
-
670
-
667
+
668
+
671
669
import com.google.android.material.navigation.NavigationView ;
672
-
670
+
673
671
public class MainActivity extends AppCompatActivity
674
672
implements NavigationView .OnNavigationItemSelectedListener ,
675
673
OnFragmentInteractionListener {
676
-
674
+
677
675
enum AppFragment {
678
676
SingleAccount ,
679
677
MultipleAccount ,
680
678
B2C
681
679
}
682
-
680
+
683
681
private AppFragment mCurrentFragment;
684
-
682
+
685
683
private ConstraintLayout mContentMain;
686
-
684
+
687
685
@Override
688
686
protected void onCreate (Bundle savedInstanceState ) {
689
687
super . onCreate(savedInstanceState);
690
688
setContentView(R . layout. activity_main);
691
-
689
+
692
690
mContentMain = findViewById(R . id. content_main);
693
-
691
+
694
692
Toolbar toolbar = findViewById(R . id. toolbar);
695
693
setSupportActionBar(toolbar);
696
694
DrawerLayout drawer = findViewById(R . id. drawer_layout);
@@ -700,92 +698,92 @@ Follow these steps to create a new project if you don't already have an Android
700
698
drawer. addDrawerListener(toggle);
701
699
toggle. syncState();
702
700
navigationView. setNavigationItemSelectedListener(this );
703
-
701
+
704
702
// Set default fragment
705
703
navigationView. setCheckedItem(R . id. nav_single_account);
706
704
setCurrentFragment(AppFragment . SingleAccount );
707
705
}
708
-
706
+
709
707
@Override
710
708
public boolean onNavigationItemSelected (final MenuItem item ) {
711
709
final DrawerLayout drawer = findViewById(R . id. drawer_layout);
712
710
drawer. addDrawerListener(new DrawerLayout .DrawerListener () {
713
711
@Override
714
712
public void onDrawerSlide (@NonNull View drawerView , float slideOffset ) { }
715
-
713
+
716
714
@Override
717
715
public void onDrawerOpened (@NonNull View drawerView ) { }
718
-
716
+
719
717
@Override
720
718
public void onDrawerClosed (@NonNull View drawerView ) {
721
719
// Handle navigation view item clicks here.
722
720
int id = item. getItemId();
723
-
721
+
724
722
if (id == R . id. nav_single_account) {
725
723
setCurrentFragment(AppFragment . SingleAccount );
726
724
}
727
-
725
+
728
726
if (id == R . id. nav_multiple_account) {
729
727
setCurrentFragment(AppFragment . MultipleAccount );
730
728
}
731
-
729
+
732
730
if (id == R . id. nav_b2c) {
733
731
setCurrentFragment(AppFragment . B2C );
734
732
}
735
-
733
+
736
734
drawer. removeDrawerListener(this );
737
735
}
738
-
736
+
739
737
@Override
740
738
public void onDrawerStateChanged (int newState ) { }
741
739
});
742
-
740
+
743
741
drawer. closeDrawer(GravityCompat . START );
744
742
return true ;
745
743
}
746
-
744
+
747
745
private void setCurrentFragment (final AppFragment newFragment ){
748
746
if (newFragment == mCurrentFragment) {
749
747
return ;
750
748
}
751
-
749
+
752
750
mCurrentFragment = newFragment;
753
751
setHeaderString(mCurrentFragment);
754
752
displayFragment(mCurrentFragment);
755
753
}
756
-
754
+
757
755
private void setHeaderString (final AppFragment fragment ){
758
756
switch (fragment) {
759
757
case SingleAccount :
760
758
getSupportActionBar(). setTitle(" Single Account Mode" );
761
759
return ;
762
-
760
+
763
761
case MultipleAccount :
764
762
getSupportActionBar(). setTitle(" Multiple Account Mode" );
765
763
return ;
766
-
764
+
767
765
case B2C :
768
766
getSupportActionBar(). setTitle(" B2C Mode" );
769
767
return ;
770
768
}
771
769
}
772
-
770
+
773
771
private void displayFragment (final AppFragment fragment ){
774
772
switch (fragment) {
775
773
case SingleAccount :
776
774
attachFragment(new com.azuresamples.msalandroidapp. SingleAccountModeFragment ());
777
775
return ;
778
-
776
+
779
777
case MultipleAccount :
780
778
attachFragment(new MultipleAccountModeFragment ());
781
779
return ;
782
-
780
+
783
781
case B2C :
784
782
attachFragment(new B2CModeFragment ());
785
783
return ;
786
784
}
787
785
}
788
-
786
+
789
787
private void attachFragment (final Fragment fragment ) {
790
788
getSupportFragmentManager()
791
789
.beginTransaction()
@@ -794,7 +792,7 @@ Follow these steps to create a new project if you don't already have an Android
794
792
.commit();
795
793
}
796
794
}
797
-
795
+
798
796
```
799
797
800
798
> [ !NOTE]
@@ -806,93 +804,93 @@ If you would like to model your UI off this tutorial, the following is a sample
806
804
807
805
1 . In ** app** > ** src** > ** main** > ** res** > ** layout** > ** activity_main.xml** . Replace the content of ** activity_main.xml** with the following code snippet to display buttons and text boxes:
808
806
809
- ``` xml
810
- <?xml version =" 1.0" encoding =" utf-8" ?>
811
- <LinearLayout xmlns : android =" http://schemas.android.com/apk/res/android"
812
- xmlns : tools =" http://schemas.android.com/tools"
813
- android : id =" @+id/activity_main"
814
- android : layout_width =" match_parent"
815
- android : layout_height =" match_parent"
816
- android : background =" #FFFFFF"
817
- android : orientation =" vertical"
818
- tools : context =" .MainActivity" >
819
-
820
- <LinearLayout
821
- android : layout_width =" match_parent"
822
- android : layout_height =" wrap_content"
823
- android : orientation =" horizontal"
824
- android : paddingTop =" 5dp"
825
- android : paddingBottom =" 5dp"
826
- android : weightSum =" 10" >
827
-
828
- <Button
829
- android : id =" @+id/signIn"
830
- android : layout_width =" 0dp"
831
- android : layout_height =" wrap_content"
832
- android : layout_weight =" 5"
833
- android : gravity =" center"
834
- android : text =" Sign In" />
835
-
836
- <Button
837
- android : id =" @+id/clearCache"
838
- android : layout_width =" 0dp"
839
- android : layout_height =" wrap_content"
840
- android : layout_weight =" 5"
841
- android : gravity =" center"
842
- android : text =" Sign Out"
843
- android : enabled =" false" />
844
-
845
- </LinearLayout >
846
- <LinearLayout
847
- android : layout_width =" match_parent"
848
- android : layout_height =" wrap_content"
849
- android : gravity =" center"
850
- android : orientation =" horizontal" >
851
-
852
- <Button
853
- android : id =" @+id/callGraphInteractive"
854
- android : layout_width =" 0dp"
855
- android : layout_height =" wrap_content"
856
- android : layout_weight =" 5"
857
- android : text =" Get Graph Data Interactively"
858
- android : enabled =" false" />
859
-
860
- <Button
861
- android : id =" @+id/callGraphSilent"
862
- android : layout_width =" 0dp"
863
- android : layout_height =" wrap_content"
864
- android : layout_weight =" 5"
865
- android : text =" Get Graph Data Silently"
866
- android : enabled =" false" />
867
- </LinearLayout >
868
-
869
- <TextView
870
- android : text =" Getting Graph Data..."
871
- android : textColor =" #3f3f3f"
872
- android : layout_width =" match_parent"
873
- android : layout_height =" wrap_content"
874
- android : layout_marginLeft =" 5dp"
875
- android : id =" @+id/graphData"
876
- android : visibility =" invisible" />
877
-
878
- <TextView
879
- android : id =" @+id/current_user"
880
- android : layout_width =" match_parent"
881
- android : layout_height =" 0dp"
882
- android : layout_marginTop =" 20dp"
883
- android : layout_weight =" 0.8"
884
- android : text =" Account info goes here..." />
885
-
886
- <TextView
887
- android : id =" @+id/txt_log"
888
- android : layout_width =" match_parent"
889
- android : layout_height =" 0dp"
890
- android : layout_marginTop =" 20dp"
891
- android : layout_weight =" 0.8"
892
- android : text =" Output goes here..." />
893
- </LinearLayout >
894
- ```
895
-
807
+ ``` xml
808
+ <?xml version =" 1.0" encoding =" utf-8" ?>
809
+ <LinearLayout xmlns : android =" http://schemas.android.com/apk/res/android"
810
+ xmlns : tools =" http://schemas.android.com/tools"
811
+ android : id =" @+id/activity_main"
812
+ android : layout_width =" match_parent"
813
+ android : layout_height =" match_parent"
814
+ android : background =" #FFFFFF"
815
+ android : orientation =" vertical"
816
+ tools : context =" .MainActivity" >
817
+
818
+ <LinearLayout
819
+ android : layout_width =" match_parent"
820
+ android : layout_height =" wrap_content"
821
+ android : orientation =" horizontal"
822
+ android : paddingTop =" 5dp"
823
+ android : paddingBottom =" 5dp"
824
+ android : weightSum =" 10" >
825
+
826
+ <Button
827
+ android : id =" @+id/signIn"
828
+ android : layout_width =" 0dp"
829
+ android : layout_height =" wrap_content"
830
+ android : layout_weight =" 5"
831
+ android : gravity =" center"
832
+ android : text =" Sign In" />
833
+
834
+ <Button
835
+ android : id =" @+id/clearCache"
836
+ android : layout_width =" 0dp"
837
+ android : layout_height =" wrap_content"
838
+ android : layout_weight =" 5"
839
+ android : gravity =" center"
840
+ android : text =" Sign Out"
841
+ android : enabled =" false" />
842
+
843
+ </LinearLayout >
844
+ <LinearLayout
845
+ android : layout_width =" match_parent"
846
+ android : layout_height =" wrap_content"
847
+ android : gravity =" center"
848
+ android : orientation =" horizontal" >
849
+
850
+ <Button
851
+ android : id =" @+id/callGraphInteractive"
852
+ android : layout_width =" 0dp"
853
+ android : layout_height =" wrap_content"
854
+ android : layout_weight =" 5"
855
+ android : text =" Get Graph Data Interactively"
856
+ android : enabled =" false" />
857
+
858
+ <Button
859
+ android : id =" @+id/callGraphSilent"
860
+ android : layout_width =" 0dp"
861
+ android : layout_height =" wrap_content"
862
+ android : layout_weight =" 5"
863
+ android : text =" Get Graph Data Silently"
864
+ android : enabled =" false" />
865
+ </LinearLayout >
866
+
867
+ <TextView
868
+ android : text =" Getting Graph Data..."
869
+ android : textColor =" #3f3f3f"
870
+ android : layout_width =" match_parent"
871
+ android : layout_height =" wrap_content"
872
+ android : layout_marginLeft =" 5dp"
873
+ android : id =" @+id/graphData"
874
+ android : visibility =" invisible" />
875
+
876
+ <TextView
877
+ android : id =" @+id/current_user"
878
+ android : layout_width =" match_parent"
879
+ android : layout_height =" 0dp"
880
+ android : layout_marginTop =" 20dp"
881
+ android : layout_weight =" 0.8"
882
+ android : text =" Account info goes here..." />
883
+
884
+ <TextView
885
+ android : id =" @+id/txt_log"
886
+ android : layout_width =" match_parent"
887
+ android : layout_height =" 0dp"
888
+ android : layout_marginTop =" 20dp"
889
+ android : layout_weight =" 0.8"
890
+ android : text =" Output goes here..." />
891
+ </LinearLayout >
892
+ ```
893
+
896
894
## Test your app
897
895
898
896
### Run locally
0 commit comments