Custom notification click listener not working in android api 26 above - android-notifications

Notification works perfectly bellow api lavel 26 but 26 and above android version notification shows but click event not working. I have MusicPlayerReceiver to handle click. Above 26 api MusicPlayerReceiver not call. but bellow 26 that call perfectly. I check stackoverflow solution but none of that work for me.
private void createNotification(SuraDetail mSongDetail) {
try {
String songName = mSongDetail.getTitle();
String authorName = mSongDetail.getArtist();
String albumName = mSongDetail.getDisplay_name();
SuraDetail audioInfo = MediaController.getInstance().getPlayingSongDetail();
RemoteViews simpleContentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.player_small_notification);
RemoteViews expandedView = null;
if (supportBigNotifications) {
expandedView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.player_small_notification);
}
Intent intent = new Intent(MyApplication.applicationContext, PobitroQuranDetailsActivity.class);
intent.setAction("openplayer");
intent.setFlags(32768);
PendingIntent contentIntent = PendingIntent.getActivity(MyApplication.applicationContext, 0, intent, 0);
Notification notification = new NotificationCompat.Builder(getApplicationContext()).setSmallIcon(R.drawable.quran)
.setContentIntent(contentIntent).setContentTitle(songName).build();
notification.contentView = simpleContentView;
if (supportBigNotifications) {
notification.bigContentView = expandedView;
}
setListeners(simpleContentView);
if (supportBigNotifications) {
setListeners(expandedView);
}
Bitmap albumArt = audioInfo != null ? audioInfo.getSmallCover(MyApplication.applicationContext) : null;
if (albumArt != null) {
notification.contentView.setImageViewBitmap(R.id.player_album_art, albumArt);
if (supportBigNotifications) {
notification.bigContentView.setImageViewBitmap(R.id.player_album_art, albumArt);
}
} else {
notification.contentView.setImageViewResource(R.id.player_album_art, R.drawable.quran);
if (supportBigNotifications) {
notification.bigContentView.setImageViewResource(R.id.player_album_art, R.drawable.quran);
}
}
notification.contentView.setViewVisibility(R.id.player_progress_bar, View.GONE);
notification.contentView.setViewVisibility(R.id.player_next, View.VISIBLE);
notification.contentView.setViewVisibility(R.id.player_previous, View.VISIBLE);
if (supportBigNotifications) {
notification.bigContentView.setViewVisibility(R.id.player_next, View.VISIBLE);
notification.bigContentView.setViewVisibility(R.id.player_previous, View.VISIBLE);
notification.bigContentView.setViewVisibility(R.id.player_progress_bar, View.GONE);
}
if (MediaController.getInstance().isAudioPaused()) {
notification.contentView.setViewVisibility(R.id.player_pause, View.GONE);
notification.contentView.setViewVisibility(R.id.player_play, View.VISIBLE);
if (supportBigNotifications) {
notification.bigContentView.setViewVisibility(R.id.player_pause, View.GONE);
notification.bigContentView.setViewVisibility(R.id.player_play, View.VISIBLE);
}
} else {
notification.contentView.setViewVisibility(R.id.player_pause, View.VISIBLE);
notification.contentView.setViewVisibility(R.id.player_play, View.GONE);
if (supportBigNotifications) {
notification.bigContentView.setViewVisibility(R.id.player_pause, View.VISIBLE);
notification.bigContentView.setViewVisibility(R.id.player_play, View.GONE);
}
}
notification.contentView.setTextViewText(R.id.player_song_name, songName);
notification.contentView.setTextViewText(R.id.player_author_name, authorName);
if (supportBigNotifications) {
notification.bigContentView.setTextViewText(R.id.player_song_name, songName);
notification.bigContentView.setTextViewText(R.id.player_author_name, authorName);
// notification.bigContentView.setTextViewText(R.id.player_albumname, albumName);
}
notification.flags |= Notification.FLAG_ONGOING_EVENT;
startForeground(1, notification);
if (remoteControlClient != null) {
RemoteControlClient.MetadataEditor metadataEditor = remoteControlClient.editMetadata(true);
metadataEditor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, authorName);
metadataEditor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, songName);
/* if (audioInfo != null && audioInfo.getCover(MyApplication.applicationContext) != null) {
metadataEditor.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK,
audioInfo.getCover(MyApplication.applicationContext));
}*/
metadataEditor.apply();
audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setListeners(RemoteViews view) {
try {
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_PREVIOUS),
PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_previous, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_close, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_pause, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_NEXT), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_next, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_PLAY), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_play, pendingIntent);
} catch (Exception e) {
e.printStackTrace();
}
}

I noticed exactly the same issue in my app. The issue is apparently caused by the way an intent is constructed, so instead of calling
new Intent(String action);
it's now required to call
new Intent (String action,
Uri uri,
Context packageContext,
Class<?> cls)

Related

Your app(s) are using a WebView that is vulnerable to cross-app scripting

My android app keeps getting rejected because of this reason:
Your app(s) are using a WebView that is vulnerable to cross-app scripting.
I already did an extensive search and found some thing I could do:
Follow the steps on https://support.google.com/faqs/answer/9084685. Since I'm using a launcher, I have to follow option 2.
I added this code in my manifest.xml: android.webkit.WebView.EnableSafeBrowsing
I'm sure the problem lies in the code posted below, where I don't use a fixed url for my loadURL, but I let it change via intent, being a notificiation url or a mail link. I'm aware this gives serious security issues, but I don't know how to fix it. In the link I provided above I want to follow option 2 but:
I can't disable javascript (my webpage won't load without it)
I don't know how to validate/secure the url in loadURL in such a way that Google allows me to upload my app to the Play Store.
Can someone please help me?
#Override
protected void onCreate(Bundle savedInstanceState) {
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("send-url"));
super.onCreate(savedInstanceState);
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
String default_url = "https://www.playday.be/app/";
FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(task -> {
if (task.isSuccessful() && task.getResult() != null) {
String refreshedToken = task.getResult();
Log.v("newToken",refreshedToken);
sendRegistrationToServer(refreshedToken);
}
});
if(getIntent().getExtras() != null){
if (getIntent().getExtras().getString("pushUrl") != null) {
String url_from_notif = getIntent().getExtras().getString("pushUrl");
if(Patterns.WEB_URL.matcher(url_from_notif).matches()) {
default_url = url_from_notif;
Log.v("url_from_notif = ", default_url);
}
}
if (getIntent().getData() != null) {
String url_from_mail = getIntent().getData().toString();
url_from_mail = url_from_mail.replace("playday://", "");
if(Patterns.WEB_URL.matcher(url_from_mail).matches()) {
default_url = url_from_mail;
Log.v("url_from_mail = ", default_url);
}
}
}
Log.v("default_url_new = ", "" +default_url);
webView = findViewById(R.id.ifView);
assert webView != null;
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setGeolocationEnabled(false);
webView.setWebViewClient(new Callback());
webView.setWebViewClient(new MyAppWebViewClient(){
public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl) {
try {
webView.stopLoading();
} catch (Exception e) {
Log.v("method:", "onReceivedError");
}
if (webView.canGoBack()) {
webView.goBack();
}
webView.loadUrl("about:blank");
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Je bent niet online...");
alertDialog.setIcon(R.mipmap.ic_launcher);
alertDialog.setMessage("Gelieve je internetconnectie te herstellen en probeer dan opnieuw.");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Probeer opnieuw", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
startActivity(getIntent());
}
});
try {
alertDialog.show();
} catch(Exception e){
Log.e(TAG,"show dialog error no internet connection");
}
super.onReceivedError(webView, errorCode, description, failingUrl);
}
});
webView.loadUrl(default_url);
webView.setWebChromeClient(new WebChromeClient() {
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
Log.d(TAG,"111 ShowFileChooser For Android 5.0 ");
if (Build.VERSION.SDK_INT >= 23) {
if (mUMA != null) {
mUMA.onReceiveValue(null);
}
mUMA = filePath;
Log.d(TAG,"ShowFileChooser For Android 5.0 SDK_INT>=23 chk permission");
String[] PERMISSIONS = {android.Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST_CAMERA);
} else {
Log.d(TAG,"112 ShowFileChooser For Android 5.0 in IF SDK_INT>=23 permission grant");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCM);
} catch (Exception ex) {
// Error occurred while creating the File
Log.e(TAG, "Unable to create Image File 1", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCM = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FCR);
}
} else {
Log.d(TAG,"113 ShowFileChooser For Android 5.0 in else SDK_INT>=23");
if (mUMA != null) {
mUMA.onReceiveValue(null);
}
mUMA = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCM);
} catch (Exception ex) {
// Error occurred while creating the File
Log.e(TAG, "Unable to create Image File 2", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCM = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FCR);
}
// Double check that we don't have any existing callbacks
return true;
}
});
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = "1";
String channel2 = "2";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(channelId,
"Channel 1", NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setDescription("This is BNT");
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setShowBadge(true);
assert notificationManager != null; //edit 1402
notificationManager.createNotificationChannel(notificationChannel);
NotificationChannel notificationChannel2 = new NotificationChannel(channel2,
"Channel 2", NotificationManager.IMPORTANCE_MIN);
notificationChannel.setDescription("This is bTV");
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setShowBadge(true);
notificationManager.createNotificationChannel(notificationChannel2);
}
}
I finally figured it out myself and got my app approved in the app store.
I just needed to validate/sanitize the url that was loaded in the webview.
I changed the code:
if(getIntent().getExtras() != null){
if (getIntent().getExtras().getString("pushUrl") != null) {
String url_from_notif = getIntent().getExtras().getString("pushUrl");
if(Patterns.WEB_URL.matcher(url_from_notif).matches()) {
default_url = url_from_notif;
Log.v("url_from_notif = ", default_url);
}
}
if (getIntent().getData() != null) {
String url_from_mail = getIntent().getData().toString();
url_from_mail = url_from_mail.replace("playday://", "");
if(Patterns.WEB_URL.matcher(url_from_mail).matches()) {
default_url = url_from_mail;
Log.v("url_from_mail = ", default_url);
}
}
}
To:
if(getIntent().getExtras() != null){
String url_from_notif = getIntent().getExtras().getString("pushUrl");
if (url_from_notif != null) {
if(URLUtil.isValidUrl(url_from_notif) && Patterns.WEB_URL.matcher(url_from_notif).matches()) {
default_url = url_from_notif;
Log.v("url_from_notif = ", default_url);
}
}
if (getIntent().getData() != null) {
String url_from_mail = getIntent().getData().toString();
url_from_mail = url_from_mail.replace("playday://", "");
if(URLUtil.isValidUrl(url_from_mail) && Patterns.WEB_URL.matcher(url_from_mail).matches()) {
default_url = url_from_mail;
Log.v("url_from_mail = ", default_url);
}
}
}
And:
webView.loadUrl(default_url);
To:
URI uri;
try {
uri = new URI(default_url);
String domain = uri.getHost();
if (!default_url.startsWith("https://www.playday.be") || !domain.equals("www.playday.be") || !URLUtil.isValidUrl(default_url) || !Patterns.WEB_URL.matcher(default_url).matches()) {
webView.loadUrl("about:blank");
} else {
webView.loadUrl(default_url);
}
} catch (URISyntaxException e) {
e.printStackTrace();
}

Merging more than 2 accounts into one

I have a quite strange or somewhat understandable(?) problem.
My firebase project support 4 types of authentications: Google, Apple, Facebook and anonymous.
I created 2 accounts. One has Google linked with facebook, the other one has apple only.
Then I link same facebook account that is already linked with google at apple account.
Firebase console shows no change but everytime I login into apple account, firebase returns google's UID.
I kinda understand that there are all linked into one account but I don't get why the apple's UID isn't removed and google's UID doesn't have apple provider from firebase console.
Another case:
Create 3 accounts: Google, Apple and Facebook separately.
Link all together into one. every time whichever I login into, firebase returns facebook's UID. (this is something that I completely unable to understand why.)
If it's normal, should I manage them manually on console or my project if I want to see it as one account on firebase console?
Edit:
firebase console
Unity FirebaseAuth.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Firebase.Auth;
using System.Text;
using System.Security.Cryptography;
using UnityEngine.SocialPlatforms;
#if !UNITY_IOS
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using GooglePlayGames.OurUtils;
#else
using AppleAuth;
using AppleAuth.Native;
using AppleAuth.Enums;
using AppleAuth.Extensions;
using AppleAuth.Interfaces;
#endif
public class FirebaseAuth : MonoBehaviour
{
public enum eMOBILEPLATFORM_STATUS
{
CONNECTED,
DISCONNECT,
ERROR,
LOGIN_WAIT,
};
private static FirebaseAuth _instance;
protected eMOBILEPLATFORM_STATUS _accountStatus = eMOBILEPLATFORM_STATUS.DISCONNECT;
#if UNITY_IOS
private IAppleAuthManager _appleAuthManager;
#endif
public eMOBILEPLATFORM_STATUS Status { get { return _accountStatus; } }
public FirebaseAuth auth;
private string _accessToken = string.Empty;
public static FirebaseAuth Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType(typeof(FirebaseAuth)) as FirebaseAuth;
if (_instance == null)
{
Debug.LogError("Missing GlobalObject, Use for Firebase");
return null;
}
}
return _instance;
}
}
void Update()
{
#if UNITY_IOS
if (_appleAuthManager != null) _appleAuthManager.Update();
#endif
}
public void Init()
{
#if !UNITY_IOS
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration
.Builder()
.RequestServerAuthCode(false)
.RequestIdToken()
.Build();
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.DebugLogEnabled = true;
PlayGamesPlatform.Activate();
#else
if (AppleAuthManager.IsCurrentPlatformSupported)
{
var deserializer = new PayloadDeserializer();
_appleAuthManager = new AppleAuthManager(deserializer);
}
#endif
Debug.Log("Firebase Init");
auth = FirebaseAuth.DefaultInstance;
_accessToken = string.Empty;
}
#if !UNITY_IOS
public void TryGoogleLogin(bool newLogin = true)
{
if (!Social.localUser.authenticated)
{
Social.localUser.Authenticate(success =>
{
if (success)
{
Debug.Log("login success. " + Social.localUser.userName);
if (newLogin)
{
StartCoroutine(TryGoogleFirebaseLogin(newLogin));
}
else
{
LinkGoogleFirebase();
}
}
else
{
Debug.Log("login failed");
}
});
}
else
{
if (newLogin)
{
StartCoroutine(TryGoogleFirebaseLogin(newLogin));
}
else
{
LinkGoogleFirebase();
}
}
}
public void TryGoogleLogout()
{
if (Social.localUser.authenticated)
{
PlayGamesPlatform.Instance.SignOut();
TryFirebaseLogout();
Debug.Log("logout - done");
}
}
public IEnumerator TryGoogleFirebaseLogin(bool newLogin = true)
{
if (newLogin)
{
auth.Dispose();
auth = FirebaseAuth.DefaultInstance;
}
while (string.IsNullOrEmpty(((PlayGamesLocalUser)Social.localUser).GetIdToken()))
yield return null;
string idToken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
_accessToken = idToken;
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("google-CredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("google-CredentialAsync encountered and error: " + task.Exception);
return;
}
Debug.Log("google login success! :D " + auth.CurrentUser.UserId);
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
UserConfig.Instance.SaveMobilePlatformLogin(true);
PlayerInfo.Instance.m_bGlobalMobilePlatformLogin = true;
if (DoesProvierExist("facebook.com"))
{
PlayerInfo.Instance.m_bGlobalGuestLogin = false;
UserConfig.Instance.SaveFacebookLogin(true);
FacebookManager.Instance.ChangeFacebookStatus(FacebookManager.eFACEBOOK_STATUS.CONNECTED);
}
});
}
public void LinkGoogleFirebase()
{
if (auth != null)
{
string idToken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("google-LinkWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("google-LinkWithCredentialAsync encountered an error: " + task.Exception);
return;
}
FirebaseUser newUser = task.Result;
Debug.Log("google-Credentials successfully linked to Firebase user: " + newUser.DisplayName + "(" + newUser.UserId + ")");
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
});
}
}
#endif
public IEnumerator TryFacebookFirebaseLogin(Facebook.Unity.AccessToken accessToken, bool newLogin = false)
{
if (newLogin)
{
auth = FirebaseAuth.DefaultInstance;
}
while (System.String.IsNullOrEmpty(accessToken.TokenString))
yield return null;
_accessToken = accessToken.TokenString;
auth = FirebaseAuth.DefaultInstance;
Credential credential = FacebookAuthProvider.GetCredential(accessToken.TokenString);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("facebook-CredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("facebook-CredentialAsync encountered and error: " + task.Exception);
return;
}
Debug.Log("facebook firebase success! :D " + auth.CurrentUser.UserId);
#if !UNITY_IOS
if(DoesProvierExist("google.com"))
#else
if(DoesProvierExist("apple.com"))
#endif
{
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
}
});
}
public void LinkFacebookFirebase(Facebook.Unity.AccessToken accessToken)
{
if (auth != null)
{
Credential credential = FacebookAuthProvider.GetCredential(accessToken.TokenString);
auth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("facebook-LinkWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("facebook-LinkWithCredentialAsync encountered an error: " + task.Exception);
return;
}
FirebaseUser newUser = task.Result;
Debug.Log("facebook-Credentials successfully linked to Firebase user: " + newUser.DisplayName + "(" + newUser.UserId + ")");
FacebookManager.Instance.ChangeFacebookStatus(FacebookManager.eFACEBOOK_STATUS.CONNECTED);
});
}
}
#if UNITY_IOS
public IEnumerator TryAppleFirebaseLogin(bool newLogin = true)
{
if (newLogin)
{
auth.Dispose();
auth = FirebaseAuth.DefaultInstance;
}
string rawNonce = GenerateRandomString(32);
string nonce = GenerateSHA256NonceFromRawNonce(rawNonce);
var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce);
while (auth==null)
yield return null;
_appleAuthManager.LoginWithAppleId(
loginArgs,
credential =>
{
var appleIdCredential = credential as IAppleIDCredential;
var identityToken = Encoding.UTF8.GetString(appleIdCredential.IdentityToken);
var authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode);
var firebaseCredential = OAuthProvider.GetCredential("apple.com", identityToken, rawNonce, authorizationCode);
auth.SignInWithCredentialAsync(firebaseCredential);
if (appleIdCredential.FullName != null)
{
var userName = appleIdCredential.FullName.ToLocalizedString();
var profile = new UserProfile();
profile.DisplayName = userName;
auth.CurrentUser.UpdateUserProfileAsync(profile);
}
_accessToken = authorizationCode.ToString();
Debug.Log("apple firebase success! :D " + auth.CurrentUser.UserId);
_accountStatus = eMOBILEPLATFORM_STATUS.CONNECTED;
UserConfig.Instance.SaveMobilePlatformLogin(true);
PlayerInfo.Instance.m_bGlobalMobilePlatformLogin = true;
if (DoesProvierExist("facebook.com"))
{
PlayerInfo.Instance.m_bGlobalGuestLogin = false;
UserConfig.Instance.SaveFacebookLogin(true);
}
},
error =>
{
var authorizationErrorCode = error.GetAuthorizationErrorCode();
switch (authorizationErrorCode)
{
case AuthorizationErrorCode.Canceled:
break;
case AuthorizationErrorCode.Unknown:
case AuthorizationErrorCode.InvalidResponse:
case AuthorizationErrorCode.NotHandled:
case AuthorizationErrorCode.Failed:
Debug.LogError("apple-login failed :/ error code: " + authorizationErrorCode);
break;
}
return;
});
}
#endif
public IEnumerator TryGuestFirebaseLogin(bool newLogin = false)
{
if (newLogin)
{
auth.Dispose();
auth = FirebaseAuth.DefaultInstance;
}
while (auth == null)
yield return null;
auth.SignInAnonymouslyAsync().ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("guest-SignInAnonymouslyAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("guest-SignInAnonymouslyAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.Log("guest-User signed in successfully :D " + newUser.DisplayName + " (" + newUser.UserId + ")");
});
}
public void UnlinkFirebase(string providerID)
{
if (auth != null && DoesProvierExist(providerID))
{
auth.CurrentUser.UnlinkAsync(providerID).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError(providerID + "-UnlinkAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError(providerID + "-UnlinkAsync encountered an error: " + task.Exception);
return;
}
// The user has been unlinked from the provider.
FirebaseUser newUser = task.Result;
Debug.LogFormat(providerID + " Credentials successfully unlinked from user: {0} ({1})", newUser.DisplayName, newUser.UserId);
#if !UNITY_IOS
if (providerID == "google.com")
#else
if (providerID == "apple.com")
#endif
{
_accountStatus = eMOBILEPLATFORM_STATUS.DISCONNECT;
}
});
}
}
public void TryFirebaseLogout()
{
auth.SignOut();
}
private string GenerateRandomString(int length)
{
const string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
var cryptographicallySecureRandomNumberGenerator = new RNGCryptoServiceProvider();
var result = string.Empty;
var remainingLength = length;
var randomNumberHolder = new byte[1];
while (remainingLength > 0)
{
var randomNumbers = new List<int>(16);
for (var randomNumberCount = 0; randomNumberCount < 16; randomNumberCount++)
{
cryptographicallySecureRandomNumberGenerator.GetBytes(randomNumberHolder);
randomNumbers.Add(randomNumberHolder[0]);
}
for (var randomNumberIndex = 0; randomNumberIndex < randomNumbers.Count; randomNumberIndex++)
{
if (remainingLength == 0)
{
break;
}
var randomNumber = randomNumbers[randomNumberIndex];
if (randomNumber < charset.Length)
{
result += charset[randomNumber];
remainingLength--;
}
}
}
return result;
}
private string GenerateSHA256NonceFromRawNonce(string rawNonce)
{
var sha = new SHA256Managed();
var utf8RawNonce = Encoding.UTF8.GetBytes(rawNonce);
var hash = sha.ComputeHash(utf8RawNonce);
var result = string.Empty;
for (var i = 0; i < hash.Length; i++)
{
result += hash[i].ToString("x2");
}
return result;
}
public string GetAccessToken()
{
return _accessToken;
}
/// <summary>
/// Check the current user has certain provierID.
/// </summary>
/// <param name="providerID"> Such as "facebook.com", "apple.com", "google.com"</param>
/// <returns>false if auth or user is null</returns>
public bool DoesProvierExist(string providerID)
{
FirebaseUser user = auth.CurrentUser;
bool result = false;
int checkCount = 0;
List<string> providers = new List<string>();
if (user != null)
{
foreach (var profile in user.ProviderData)
{
checkCount++;
providers.Add(profile.ProviderId);
if (profile.ProviderId == providerID)
result = true;
}
}
#if _USE_DEBUG_LOG_
string temp = string.Empty;
for (int i = 0; i < providers.Count; i++)
{
temp += providers[i];
if (i != providers.Count - 1)
temp += ", ";
}
Debug.Log("Just in case if you wanna know. There are " + checkCount + " providerID at this account\n"+temp);
#endif
return result;
}
}
and here's xcode log of iphone.
ClickButton (GlobalStart)(04/16/2021 10:22:56)
UIEventButtonClick:OnClick()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
LoginFacebook()False
FacebookManager:LoginFacebook()
UIL_Login:Event_Click(String)
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
2021-04-16 10:22:56.640715+0900 firebaseProject[1006:67274] -canOpenURL: failed for URL: "fbauth2:/" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"
-> applicationWillResignActive()
-> applicationDidBecomeActive()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
2021-04-16 10:22:58.701301+0900 firebaseProject[1006:68330] [tcp] tcp_input [C19.1:3] flags=[R] seq=3046356287, ack=0, win=0 state=CLOSED rcv_nxt=3046356287, snd_una=716434727
2021-04-16 10:22:58.705125+0900 firebaseProject[1006:68330] [tcp] tcp_input [C19.1:3] flags=[R] seq=3046356287, ack=0, win=0 state=CLOSED rcv_nxt=3046356287, snd_una=716434727
CONNECTTING() True
FacebookManager:Connectting()
Facebook.Unity.CallbackManager:TryCallCallback(Object, IResult)
Facebook.Unity.CallbackManager:CallCallback(Object, IResult)
Facebook.Unity.CallbackManager:OnFacebookResponse(IInternalResult)
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
facebook-LinkWithCredentialAsync encountered an error: System.AggregateException: Exception of type 'System.AggregateException' was thrown.
-----------------
Firebase.FirebaseException: [ERROR_PROVIDER_ALREADY_LINKED] - User can only be linked to one identity for the given provider.
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetException(AggregateException)
System.Threading.Tasks.TaskCompletionSource`1:SetException(Exception)
Firebase.Auth.<GetTask>c__AnonStorey0:<>m__0()
Firebase.Auth.Future_User:SWIG_CompletionDispatcher(Int32)
Firebase.AppUtil:PollCallbacks()
Firebase.Platform.FirebaseHandler:Update()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
2021-04-16 10:23:01.367311+0900 firebaseProject[1006:67777] [tcp] tcp_input [C23.1:3] flags=[R] seq=3109184249, ack=0, win=0 state=CLOSED rcv_nxt=3109184249, snd_una=2797527191
2021-04-16 10:23:01.367444+0900 firebaseProject[1006:67777] [tcp] tcp_input [C23.1:3] flags=[R] seq=3109184249, ack=0, win=0 state=CLOSED rcv_nxt=3109184249, snd_una=2797527191
facebook firebase success! :D 5ThQ■■■■■■■■■■■■■■
<TryFacebookFirebaseLogin>c__Iterator0:<>m__0(Task`1)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
Firebase.Auth.<GetTask>c__AnonStorey0:<>m__0()
Firebase.Auth.Future_User:SWIG_CompletionDispatcher(Int32)
Firebase.AppUtil:PollCallbacks()
Firebase.Platform.FirebaseHandler:Update()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
Just in case if you wanna know. There are 1 providerID at this account
facebook.com
FirebaseAuth:DoesProvierExist(String)
<TryFacebookFirebaseLogin>c__Iterator0:<>m__0(Task`1)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
System.Threading.Tasks.<ContinueWith>c__AnonStorey0:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey2:<>m__0(Task)
System.Threading.Tasks.<ContinueWith>c__AnonStorey1:<>m__0()
System.Threading.Tasks.Task:<immediateExecutor>m__1(Action)
System.Threading.Tasks.Task`1:RunContinuations()
System.Threading.Tasks.Task`1:TrySetResult(T)
System.Threading.Tasks.TaskCompletionSource`1:SetResult(T)
Firebase.Auth.<GetTask>c__AnonStorey0:<>m__0()
Firebase.Auth.Future_User:SWIG_CompletionDispatcher(Int32)
Firebase.AppUtil:PollCallbacks()
Firebase.Platform.FirebaseHandler:Update()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
ClickButton (LogInBtn)(04/16/2021 10:23:11)
UIEventButtonClick:OnClick()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
firebase apple in
<TryAppleFirebaseLogin>c__Iterator1:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
UIC_OptionPanel:_LinkMobilePlatform(E_MESSAGEBOX_CONFIRM_TYPE)
Messenger`1:Broadcast(String, T, MessengerMode)
UIC_MessageBox_Button:OnClick()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
-> applicationWillResignActive()
-> applicationDidBecomeActive()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
apple firebase success! :D 5ThQ■■■■■■■■■■■■■■
<TryAppleFirebaseLogin>c__AnonStorey3:<>m__0(ICredential)
AppleAuth.CallbackHandler:ExecutePendingCallbacks()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
Just in case if you wanna know. There are 1 providerID at this account
facebook.com
FirebaseAuth:DoesProvierExist(String)
<TryAppleFirebaseLogin>c__AnonStorey3:<>m__0(ICredential)
AppleAuth.CallbackHandler:ExecutePendingCallbacks()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
So... I found that lack of knowledge about whatever I'm doing goes very wrong...
I used apple-signin-unity by lupidan from github and mixing various tutorials that I could found on google to expect it's working. :|
Firebase blocks linking multiple accounts that already registered.
Mine just dispose previous FirebaseAuth and overwrite new one.
that is why it looked like merging accounts that actually doesn't do anything right.
I should have been more careful before I ask question.
Edit:
What was actually going on is that there's no exception at apple login.
Others have exceptions by using "ContinueWith" function but apple doesn't.
by adding it, everything works okay.

Unity - The name 'auth' does not exist in the current context

I am currently trying to create user authentication in unity and I am having some issues.
The code below is what I have at the moment and I keep receiving the error saying Auth does not exist in the current context.
Does anyone have any idea why this is? Probably a simple fix that I am just overlooking.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using System.Text.RegularExpressions;
using Firebase;
using Firebase.Auth;
public class Register : MonoBehaviour {
public GameObject email;
public GameObject password;
public GameObject confPassword;
private string Email;
private string Password;
private string ConfPassword;
private string form;
private bool EmailValid = false;
private string[] Characters = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
"1","2","3","4","5","6","7","8","9","0","_","-"};
public void RegisterButton(){
bool EM = false;
bool PW = false;
bool CPW = false;
if (Email != ""){
EmailValidation();
if (EmailValid){
if(Email.Contains("#")){
if(Email.Contains(".")){
EM = true;
} else {
Debug.LogWarning("Email is Incorrect");
}
} else {
Debug.LogWarning("Email is Incorrect");
}
} else {
Debug.LogWarning("Email is Incorrect");
}
} else {
Debug.LogWarning("Email Field Empty");
}
if (Password != ""){
if(Password.Length > 5){
PW = true;
} else {
Debug.LogWarning("Password Must Be atleast 6 Characters long");
}
} else {
Debug.LogWarning("Password Field Empty");
}
if (ConfPassword != ""){
if (ConfPassword == Password){
CPW = true;
} else {
Debug.LogWarning("Passwords Don't Match");
}
} else {
Debug.LogWarning("Confirm Password Field Empty");
}
if (EM == true&&PW == true&&CPW == true)
{
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
// Firebase user has been created.
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("Firebase user created successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
}
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Tab)){
if (email.GetComponent<InputField>().isFocused){
password.GetComponent<InputField>().Select();
}
if (password.GetComponent<InputField>().isFocused){
confPassword.GetComponent<InputField>().Select();
}
}
if (Input.GetKeyDown(KeyCode.Return)){
if (Password != ""&&Email != ""&&Password != ""&&ConfPassword != ""){
RegisterButton();
}
}
Email = email.GetComponent<InputField>().text;
Password = password.GetComponent<InputField>().text;
ConfPassword = confPassword.GetComponent<InputField>().text;
}
void EmailValidation(){
bool SW = false;
bool EW = false;
for(int i = 0;i<Characters.Length;i++){
if (Email.StartsWith(Characters[i])){
SW = true;
}
}
for(int i = 0;i<Characters.Length;i++){
if (Email.EndsWith(Characters[i])){
EW = true;
}
}
if(SW == true&&EW == true){
EmailValid = true;
} else {
EmailValid = false;
}
}
}
I do not see you ever creating the variable auth?
While you refer to it here:
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
So I assume you will have to create a variable auth and instantiate it with something related to FireBase.Auth (unless I am overlooking something).

refresh adapter with recyclerview using D-pad holding focus

I am stuck on a complex situation, when I am refreshing my adapter of recyclerview by notifyDataSetChanged, while it having focus on particular cell (with D-PAD), is being loss. After refresh focus is not showing
private void refreshedData() {
flag1 = true;
// new MyAsycTas().execute();
focusedElement();
// select();
runnable = new Runnable() {
#Override
public void run() {
Log.e(TAG, "Data refreshed starrt.......");
// isRefreshedData = true;
fetchXmlFromUrl = new FetchDataFromUrl(Demo2Activity.this, 0, Demo2Activity.this);
handler.removeCallbacks(runnable);
select();
handler.postDelayed(runnable, 9000);
}
};
// handler.postDelayed(runnable,
// Integer.valueOf(MyStaticClass.refreshTime) * 60000);
handler.postDelayed(runnable, 9000);
}
...
public void select() {
if (verticalListView != null) {
View view = verticalListView.getChildAt(vertical_position);
if (view != null) {
view = verticalListView.getChildAt(vertical_position);
recyclerView = (RecyclerView) view.findViewById(R.id.horizontal_recyclerview);
if (recyclerView != null) {
verticalListView.scrollToPosition(vertical_position);
((View) recyclerView.getChildAt(horizontal_position)).findViewById(R.id.cat_button_thumabnail)
.requestFocus();
} else {
LinearLayout linearLayout = (LinearLayout) view.findViewById(R.id.home_fragment_menu_container);
linearLayout.getChildAt(horizontal_position).requestFocus();
}
}
}
// refreshedData();
}
..
public void focusedElement() {
if (verticalListView != null) {
View view = verticalListView.getLayoutManager().getFocusedChild();
if (view != null) {
recyclerView = (RecyclerView) view.findViewById(R.id.horizontal_recyclerview);
if (recyclerView != null) {
vertical_position = (Integer) recyclerView.getTag();
horizontal_position = recyclerView.getChildAdapterPosition(recyclerView.getFocusedChild());
} else {
LinearLayout ll = (LinearLayout) view.findViewById(R.id.home_fragment_menu_container);
horizontal_position = ll.indexOfChild(ll.getFocusedChild());
}
}
}
}

No 'output' extra specified Exception

I use the Google Photo app to pick gallery photo and then when I crop the picture and save, it catches an exception, Here is my code :
goto_picture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
IMAGE_UNSPECIFIED);
startActivityForResult(intent, PHOTO_ZOOM);
dialog.cancel();
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PHOTO_GRAPH) {
startPhotoZoom(Uri.fromFile(file));
String imagePath = SystemUtils.getSDPath() + "/temp.jpg";
File picture = new File(imagePath);
if (picture.exists()) {
pictureBitmap = BitmapFactory.decodeFile(imagePath);
ImageUtils.SaveCacheBitmap(pictureBitmap);
rvEditAvatar.setImageBitmap(pictureBitmap);
}
}
if (requestCode == PHOTO_ZOOM) {
startPhotoZoom(data.getData());
}
if (requestCode == PHOTO_RESULT) {
Bundle extras = data.getExtras();
if (extras != null) {
pictureBitmap = extras.getParcelable("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 100,
stream);
ImageUtils.SaveCacheBitmap(pictureBitmap);
rvEditAvatar.setImageBitmap(pictureBitmap);
}
}
}
}
public void startPhotoZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 180);
intent.putExtra("outputY", 180);
intent.putExtra("return-data", true);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, PHOTO_RESULT);
}
Logcat:
Process: com.google.android.apps.photos, PID: 7031
java.lang.RuntimeException: Unable to resume activity
{com.google.android.apps.photos/com.google.android.apps.photos.photoeditor.intents.EditActivity}:
java.lang.UnsupportedOperationException: No 'output' extra specified
and can not save to specified inputUri:
content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F72072/ACTUAL
As the exception said, you have to specify output extra like the following code.
intent.putExtra(MediaStore.EXTRA_OUTPUT, someOutPutPath);
And return data is not secure in case of big image cropped which may cause crash. I think that's why it forces you to use an output extra but not the data directly. So you may set the return-data to false as well:
intent.putExtra("return-data", false);
I meet this problem today, and solved by double check the data pass-back.I test following code on both Android L and Android 4. On Android L the fileUri is not empty while pre Android L we got fileUri null(in this case, I got the bitmap by simply getData).
private Bitmap decodeBitmapFromCrop(Intent data) {
Bundle extras = data.getExtras();
Bitmap photo = null;
if (extras != null) {
photo = extras.getParcelable("data");
} else {
Uri fileUri = data.getData();
if (fileUri != null) {
try {
photo = MediaStore.Images.Media.getBitmap(getContentResolver(), fileUri);
} catch (IOException e) {
XXLog.d(TAG, "Media.getBitmap", e);
}
}
}
return photo;
}

Resources