I am using social auth library for sharing and login with social media in android app.
I have logged in and authorize successfully with facebook.
But when I try to signout app crashed with nullpointer exception
adapter.signOut(getActivity(), Provider.FACEBOOK.toString());
Getting below error:
05-09 10:24:23.010: E/AndroidRuntime(19998): java.lang.NullPointerException
05-09 10:24:23.010: E/AndroidRuntime(19998): at org.brickred.socialauth.android.SocialAuthAdapter.signOut(SocialAuthAdapter.java:797)
I am using latest version. socialauth-4.4.jar and socialauth-android-3.2.jar
Please make sure to call from activity. Getactivity() from fragment not working after calling method from activity like this will work adapter.signOut(this, Provider.FACEBOOK);
I had a similar problem, this solution works for me:
https://code.google.com/p/socialauth-android/issues/detail?id=108#c16
basically there is a bug in the log out function, you have to log in before log out, otherwise you may get an NPE. the solution above is create a new SocialAuthManager when necessary.
I suggest to import that source code as a java module instead of using the jar file, so you can fix something by yourself, like change the dialog title text, etc...
In signOut function put these lines,
if (providerName != null) {
if (socialAuthManager == null) {
socialAuthManager = new SocialAuthManager();
try {
loadConfig(ctx);
} catch (Exception e) {
Log.d(" SocialAuthAdapter ", "Could not load configuration");
}
}
before
if (socialAuthManager.getConnectedProvidersIds().contains(providerName)) socialAuthManager.disconnectProvider(providerName);
This has solved the issue for me for now, in the class where you would like to sign out instantiate a new adapter if the application-wide adapter is null
//My Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
//Get the currently available adapter
myApp = (MyApplication) getApplication();
adapter = myApp.getSocialAuthAdapter();
//Adapter initialization if null
if (adapter==null){
adapter = new SocialAuthAdapter(new ResponseListener());
}
}
//ResponseListener Class
public final class ResponseListener implements DialogListener {
#Override
public void onComplete(Bundle values) {
String providerName = values.getString(SocialAuthAdapter.PROVIDER);
// Set a application wide reference to the social adapter here
myApp = (MyApplication) getApplication();
myApp.setSocialAuthAdapter(adapter);
}
#Override
public void onError(SocialAuthError error) {
Log.d("Custom-UI", "Error");
error.printStackTrace();
}
#Override
public void onCancel() {
Log.d("Custom-UI", "Cancelled");
}
#Override
public void onBack() {
Log.d("Custom-UI", "Dialog Closed by pressing Back Key");
}
}
//Code for application class
public class MyApplication extends Application {
// SocialAuth Component
private SocialAuthAdapter socialAuthAdpater;
public SocialAuthAdapter getSocialAuthAdapter() {
return socialAuthAdpater;
}
public void setSocialAuthAdapter(SocialAuthAdapter socialAuthAdapter) {
this.socialAuthAdpater = socialAuthAdapter;
}
Related
I am trying to set up android app link for my app. The problem is that the intent is received by an activity and I need to send this event to my javascript code(to navigate to the correct screen) through RCTDeviceEventEmitter but for this to happen I need to get react context somehow in my activity's code...I have no idea how to do this..This is what I have tried:
public class NewFriendActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
class ReactContextFetcher extends ReactContextBaseJavaModule {
#Override
public String getName() {
return "ReactContextFetcher";
}
public ReactContext fetchReactContext() {
return getReactApplicationContext();
}
}
Intent intent = getIntent();
String data = intent.getData().toString();
String user = data.split("/add-friend/")[1];
Log.d("obscure_tag", user);
ReactContext rContext = new ReactContextFetcher().fetchReactContext();
Log.d("obscure_tag", "this is run as well..");
sendEvent(rContext, "NewFriend", user);
}
private void sendEvent(ReactContext reactContext,
String eventName, String user) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, user);
}
}
"user" gets logged but "this is run as well.." doesn't, the app crashes before that..So I get that fetchReactContext() is not the correct way to get react context..I referred to this but actually I did not understand what that guy is trying to say..How should I get react context in this situation?
public void doSomething(View view) {
String url, link_url, pro;
url = textIn.getText().toString();
pro = spin.getSelectedItem().toString();
c1 = new ConnectInternetClass(this);
if (!url.isEmpty()) {
if (url.contains(".") && !(url.contains(" "))) {
if (url.split("\\.").length > 1) {
if (checkConnection()) {
link_url = pro+url;
c1.execute(link_url);
} else {
Toast.makeText(this, "check your internet connection", Toast.LENGTH_SHORT).show();
myText.setText("No Internet Connection");
}
} else {
myText.setText("Unknown domain");
}
} else {
myText.setText("Invalid URL");
}
} else {
myText.setText("URL can\'t empty");
}
}
I have that code to show a web page source. I want to show the result in another activity, but I don't know how. I use the create object from the first activity, but it's not method
public class ShowActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
MainActivity ma = new MainActivity();
}
Passing data from a activity , linkUrl is your variable which data you want to pass :
Intent intent = new Intent (YourActivity.this, ShowActivity.class) ;
intent.putExtra("KEY_LINK" , linkUrl);
startActivity(intent);
Receiving data from ShowActivity , Access the data by the key in onCreate():
String url = getIntent().getStringExtra("KEY_LINK");
Link : How do I pass data between Activities in Android application?
Link : https://developer.android.com/training/basics/firstapp/starting-activity.html
Why you use this kind of things. If you want to load a web page in an activity use webview for it. no need two activities to do that. Another way you can create a class which has your doSomething method (it should be public static) and call it from an activity by using that's class object. When you coding don't create unnecessary activities.
When running the activity the first time, Parte initialization (which is inside the onCreate method) goes well:
Parse.enableLocalDatastore(this);
Parse.initialize(this, "...", "...");
Then, If I press the back button and enter again in the activity, I get an error:
java.lang.IllegalStateException: `Parse#enableLocalDatastore(Context)` must be invoked before `Parse#initialize(Context)`
Which I do not really understand why, because the Parse.enableLocalDatastore(this); is before Parse.initialize(this, "...", "...");.
Well, Ok. Then I tried to retrieve when the enableLocalDatastore has finihed, with Parse.isInitialized() method, but it is private, so I can't use it (as well as some others Parse variables I could use).
After some time, I found that If I call both methods inside a new Thread it works.
I'd like to know why the error happens and why It was solved with the Thread. Also, is there any better way to do it?
Follows the code (trimmed for the important parts):
public class RegisterActivity extends Activity {
Button linkParse;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
linkParse = (Button)findViewById(R.id.linkparse);
linkParse.setOnClickListener(new LinkParse());
linkParse.setClickable(false);
try {
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
Parse.initialize(this, "...", "...");
} catch(Exception e){
Toast.makeText(RegisterActivity.this, "Parse not started.", Toast.LENGTH_SHORT).show();
linkParse.setClickable(true);
}
}
class LinkParse implements View.OnClickListener{
#Override
public void onClick(View v) {
Thread thread = new Thread(new StartParse());
thread.start();
}
}
class StartParse implements Runnable{
#Override
public void run() {
try {
// Enable Local Datastore.
Parse.enableLocalDatastore(RegisterActivity.this);
Parse.initialize(RegisterActivity.this, "...", "...");
} catch(Exception e){
}
}
}
}
You should invoke these two lines of codes from the application class not from the activity
Parse.initialize(this, "....","....");
Parse.enableLocalDatatore(this);
There is no need to initialized this multiple times and global application state is meant to be in the application class.
Create a class and extend application and initialize your parse code there
public class MyApplication extends Application{
#Override
public void onCreate(){
super.onCreate()
Parse.initialize(this, "....", "....");
Parse.enableLocalDatastore(this)
}
}
After you have created the application class. Add it to your AndroidManifest.xml
<application android:icon="#drawable/icon"
android:label="#stringapp_name"
android:name="MyApplication">
I am working on unity android project.
I have called the android side methods from unity like this
AndroidJavaObject aObj = new AndroidJavaObject("com.mypackage.UnityBridge",param1,param2);
aObj.Call("callme");
And on Android side
public class UnityBridge{
public UnityBridge(final String param1, final int param2) {
activity = UnityPlayer.currentActivity;
this.param1= param1;
this.param2= param2;
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// INITIALIZATION OF ANDROID CLASS CONSTRUCTOR HERE
}
});
}
public void callme() {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
if(obj!= null)
{
// ANDROID METHOD CALL HERE
}
}
});
}
This much is working perfectly.
If I want to call Activity specific methods like onPause(), onResume(), so there is a method in unity to do so.
void OnApplicationPause(bool pauseStatus) {
// HERE I CAN CALL activity specific **onPause()** and **onResume()** based on pauseStatus
}
Is there anything in unity from which I can give call to onNewIntent(Intent i) of Android. If not then how is it possible to call onNewIntent()
Please help to resolve this.
I wrote a post how this problem can be solved without overriding Unity activity (its about onActivityResult but the principle is the same): https://medium.com/#tarasleskiv/unity-android-plugins-and-onactivityresult-callback-abef4b6bbc87#.6d7sl8z81
Basically you create a custom empty activity and start it just to receive these callbacks and finish it immediately after that.
Check also this post about how to create activity for onNewIntent callback: https://blog.getsocial.im/android-unity-app-and-the-intent-issue/
Here is the example code of the intermediate activity yo have to create:
public class MyDeepLinkingActivity extends Activity
{
private static String TAG = "GetSocial GetSocialDeepLinkingActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Log.v(TAG, "Forward the intent");
// Do with intent what you need to
Log.v(TAG, "Returning to main activity");
//start main activity
Intent newIntent = new Intent(this, getMainActivityClass());
this.startActivity(newIntent);
finish();
}
private Class<?> getMainActivityClass() {
String packageName = this.getPackageName();
Intent launchIntent = this.getPackageManager().getLaunchIntentForPackage(packageName);
try {
return Class.forName(launchIntent.getComponent().getClassName());
} catch (Exception e) {
Log.e(TAG, "Unable to find Main Activity Class");
return null;
}
}
}
Looks like there is no built it way to get onNewIntent callback in Unity. However i can suggest to export google android project from unity and override this method in main unity activity
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//some code
}
Or you can create android plugin with your own activity which extends unity activity, but keep in mind that some plugins could stop working if you do this.
My objective is to create a reusable libraries that I could just include if i will to make new project. Example for this is login.
I will create the login project separately, do the design and coding. Now, if I will going to use it in one of my projects, I will just have to include it as a dependency. So far, this is working, the login displayed in my new project.
The challenge that I encounter is how to treat or get the response of the results of the login to my application. Since they are separate projects,
What would be the best strategy for this. Or are there any better ways to create a reusable libraries.
Thanks
Interactivity between an Activity and a Fragment (which has been loaded on that Activity) is quite easy. You can add a public method to that Fragment and then call it in your Activity methods. Otherwise if your login process is a asynchronous task (i.e is going to be done in background thread), you probably need an interface to inform parent Activity that login process has been done.
Here's some code snippets for getting started.
public LoginFrag extends Fragment {
// Other stuff
/* This is your own method which checks user credentials */
public void check() {
boolean success = false;
// codes for checking username and password
// and then update 'success' variable
// with this code you'll inform the parent activity
if(mListener != null) {
mListener.onResult(success);
}
}
OnLoginResultListener mListener;
public void setOnLoginResultListener(OnLoginResultListener listener) {
mListener = listener;
}
public interface OnLoginResultListener {
public void onResult(boolean success);
}
}
This is the parent Activity codes:
public MainActivity extends Activity {
#Override
protected void onCreate(Bundle b) {
//Other stuff
LoginFrag login = new LoginFrag(); // from the library
login.setOnLoginResultListener(new OnLoginResultListener(){
#Override
public void onResult(boolean success) {
// do stuff here with 'success' for example:
String message;
if(success) {
message = "Congratulation! you've logged in";
} else {
message = "Ooops! login failed!";
}
console.log(message);
}
});
// Now load this fragment by 'FragmentManager'
// via 'getSupportFragmentManager()'
}
}