Intent returns null onActivityResult in Fragment - android-fragments

Android 4.4 tested in Eclipse.
I've followed the lines as developers said. So in my fragment I put:
public void tomarfoto() {
// Check Camera
if (MainActivity.if_cam) {
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
this.startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
} else {
//Toast.makeText(getActivity(), "Camera not supported", Toast.LENGTH_LONG).show();
}
}
After that, I set this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(getActivity(), "Image saved to:\n" +data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
The problem is that data intent is null and provokes this:
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=android:fragment:0, request=1888, result=-1, data=null}
to activity {com.myapp.MainActivity}: java.lang.NullPointerException
I don't understand so much but apparently the onActivityResult is disconnected from the fragment who has called it so, it can't receive data results. How can I solve this?. The launchMode="singleTask" or singleInstance is not my problem, I didn't settled this.
The pictures are saved properly in the directory held by fileUri. Help.

Related

Multiple chained API calls to fetch data, but doOnNext of PublishSubject is never reached

I have a problem to understand a chained "RXJava-Retrofit" API call. I got inspired by this and implement this class named ObservationLoader to load the data from the API bucket per bucket. When the end of data is reached the API sends a endOfRecords=true:
public Observable<PageObject<Observation>> getAllObservationDataByRegion(long taxonKey,
String regionId) {
final PublishSubject<PageObject<Observation>> subject = PublishSubject.create();
return subject.doOnSubscribe(disposable -> {
this.getData(taxonKey, regionId, 0).subscribe(subject);
})
.doOnNext(observationPageObject -> {
if (observationPageObject.isEndOfRecords()) {
// -> list is completely loaded
subject.onComplete();
} else {
int nextOffset = observationPageObject.getOffset() + 1;
this.getData(taxonKey, regionId, null, nextOffset).subscribe(subject);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<PageObject<Observation>> getData(long id,
String regionId,
int offset) {
// Get your API response value
return this.api.getObservations(id, regionId, ObservationLoader.PAGE_LIMIT, offset);
}
In my Android fragment HomeFragment I subscribe to the ObservationLoader:
ObservationLoader loader = new ObservationLoader(this.getApi());
Observable<PageObject<Observation>> observable = loader
.getAllObservationDataByRegion(this.getSelectedSpecies(), this.getSelectedRegion());
observable.subscribe(new Observer<PageObject<Observation>>() {
#Override
public void onSubscribe(Disposable d) {
Log.i(TAG, "ON_SUBSCRIBE");
}
#Override
public void onNext(PageObject<Observation> observationPageObject) {
Log.i(TAG, "ON_NEXT");
}
#Override
public void onError(Throwable e) {
Log.i(TAG, "ERROR = " + e.getMessage());
}
#Override
public void onComplete() {
Log.i(TAG, "COMPLETED");
}
});
I can see that the onSubscribe() and doOnSubscribe() are called and even the getData() is reached. I assume the API is responding correctly (a previous attempt attempt with recursion worked fine). But I never reached the doOnNext function. The observer goes straight to onComplete() and no data is received. What could be the reason?
When doOnSubscribe runs, the doesn't see any consumers yet so if getData is synchronous, there won't be any first results to trigger further results. Also if getData ends, it will complete the setup so the next getData call in doOnNext will push to an already terminated subject, ingoring all data.
You'll need a differently organized feedback loop:
// we loop back the nextOffset, in a thread-safe manner
Subject<Integer> subject = PublishSubject.<Integer>create()
.toSerialized();
// bootstrap with 0 and keep open for more offsets
subject.mergeWith(Observable.just(0))
// get the data for the current offset
.concatMap(nextOffset -> getData(taxonKey, regionId, nextOffset)
.subscribeOn(Schedulers.io())
)
// if the response is end of records, stop
.takeWhile(observationPageObject -> !observationPageObject.isEndOfRecords())
// otherwise not end of records, feedback the new offset
.doOnNext(observationPageObject ->
subject.onNext(observationPageObject.getOffset() + 1)
)
// get the data on the main thread
.observeOn(AndroidSchedulers.mainThread());

Firebase Dynamic Links in Unity

Where should I put this chunk of code in order the listener function works every time I enter the app from the deep link?
Now in my unity mobile app I have this code in the initial load, however it does not work well.
The first case of entering the app from the deep link is not being handled. Only after initial load when I click the deep link my listener function works (as the listener is already set).
Is there any solution to this issue?
void Start()
{
DynamicLinks.DynamicLinkReceived += OnDynamicLink;
}
// Display the dynamic link received by the application.
void OnDynamicLink(object sender, EventArgs args)
{
var dynamicLinkEventArgs = args as ReceivedDynamicLinkEventArgs;
Debug.LogFormat("Received dynamic link {0}", dynamicLinkEventArgs.ReceivedDynamicLink.Url.OriginalString);
}
Test this, feel free to edit.
void Start()
{
StartCoroutine(WaitLoader()); //Loader
}
public void trueAwoken()
{
DynamicLinks.DynamicLinkReceived += OnDynamicLink;
}
public IEnumerator WaitLoader()
{
int i = 0;
while (i < 5) // Potential for true load state 5 (increase this 0-1000+?, it depends on your build?)
{
i++;
//Debug.Log("Waiting: " + i + "/" + Time.deltaTime);
yield return new WaitForFixedUpdate();
}
trueAwoken();
}

Obscure Unity Firebase Realtime Database Error: "Custom Run loops are not supported"?

I am currently attemping to build a custom Editor tool for Unity that utilizes the Firebase Realtime Database. This tool would allow someone to right-click on a scene asset in the inspector and select to 'lock' or 'unlock' the scene. Within our Firebase Database, this locking is represented by a dictionary, with each scene name as a key and each value being either "locked" or "unlocked". This funcitonality will be expanded later, but for now, I'm just trying to get things set up so that I can actually connect to and use the Firebase Realtime Database.
I had looked at the Firebase Quickstart Unity project for the Realtime Database (the one that functions like a leaderboard) and saw that it worked fine. I could replace the database URL in the project with the URL for my app's database, and when I entered in values, they appeared inside my realtime database.
So, I based the code for my custom editor script on the code from the quickstart. In fact, I copy-pasted most of it. I will post the script itself, and then describe the errors I receive, as well as the lines that give the errors:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Firebase;
using Firebase.Unity.Editor;
using Firebase.Database;
[CustomEditor(typeof(SceneAsset))]
[ExecuteInEditMode]
public class SceneLockingEditor : Editor
{
static string sceneName;
DependencyStatus dependencyStatus = DependencyStatus.UnavailableOther;
protected virtual void OnEnable()
{
Debug.Log("OnEnable Called");
sceneName = target.name;
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
dependencyStatus = task.Result;
if (dependencyStatus == DependencyStatus.Available)
{
InitializeFirebase();
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + dependencyStatus);
}
});
}
// Initialize the Firebase database:
protected virtual void InitializeFirebase()
{
Debug.Log("Initializing Firebase");
FirebaseApp app = FirebaseApp.DefaultInstance;
app.SetEditorDatabaseUrl(CENSORING MY DATABASE SORRY);
if (app.Options.DatabaseUrl != null) app.SetEditorDatabaseUrl(app.Options.DatabaseUrl);
}
static TransactionResult SceneLockTransaction(MutableData mutableData)
{
List<object> sceneLocks = mutableData.Value as List<object>;
if (sceneLocks == null)
{
sceneLocks = new List<object>();
}
if(mutableData.ChildrenCount > 0)
{
//Look at every child in the scene locks directory.
foreach (var child in sceneLocks)
{
Debug.Log("Checking next child.");
if (!(child is Dictionary<string, object>))
continue;
//If we find the scene we're looking for...
Debug.Log("Checking if the scene has the name we want");
foreach(string key in ((Dictionary<string, object>)child).Keys)
{
Debug.Log("Key: " + key);
}
if(((Dictionary<string, object>)child).ContainsKey(sceneName))
{
string childLockStatus = (string)((Dictionary<string, object>)child)["lockStatus"];
//If the scene is already locked, just abort.
if (childLockStatus == "locked")
{
Debug.Log("Scene is already locked. Abort.");
return TransactionResult.Abort();
}
else
{
Debug.Log("Scene existed in the database and was not locked. Locking it.");
// If the scene existed in the database but was not locked, we will lock it.
((Dictionary<string, object>)child)[sceneName] = "locked";
// You must set the Value to indicate data at that location has changed.
mutableData.Value = sceneLocks;
return TransactionResult.Success(mutableData);
}
}
}
}
Debug.Log("Scene did not exist in the database. Adding it as locked.");
// If the scene didn't exist in the database before, we will add it as locked.
Dictionary<string, object> newSceneLock = new Dictionary<string, object>();
newSceneLock[sceneName] = "locked";
sceneLocks.Add(newSceneLock);
// You must set the Value to indicate data at that location has changed.
mutableData.Value = sceneLocks;
return TransactionResult.Success(mutableData);
}
static TransactionResult SceneUnlockTransaction(MutableData mutableData)
{
List<object> sceneLocks = mutableData.Value as List<object>;
if (sceneLocks == null)
{
sceneLocks = new List<object>();
}
if (mutableData.ChildrenCount > 0)
{
//Look at every child in the scene locks directory.
foreach (var child in sceneLocks)
{
Debug.Log("Checking next child.");
if (!(child is Dictionary<string, object>))
continue;
//If we find the scene we're looking for...
Debug.Log("Checking if the scene has the name we want");
foreach (string key in ((Dictionary<string, object>)child).Keys)
{
Debug.Log("Key: " + key);
}
if (((Dictionary<string, object>)child).ContainsKey(sceneName))
{
string childLockStatus = (string)((Dictionary<string, object>)child)["lockStatus"];
//If the scene is already locked, just abort.
if (childLockStatus == "unlocked")
{
Debug.Log("Scene is already unlocked. Abort.");
return TransactionResult.Abort();
}
else
{
Debug.Log("Scene existed in the database and was locked. Unlocking it.");
// If the scene existed in the database but was not locked, we will lock it.
((Dictionary<string, object>)child)[sceneName] = "unlocked";
// You must set the Value to indicate data at that location has changed.
mutableData.Value = sceneLocks;
return TransactionResult.Success(mutableData);
}
}
}
}
Debug.Log("Scene did not exist in the database. Adding it as unlocked.");
// If the scene didn't exist in the database before, we will add it as locked.
Dictionary<string, object> newSceneLock = new Dictionary<string, object>();
newSceneLock[sceneName] = "unlocked";
sceneLocks.Add(newSceneLock);
// You must set the Value to indicate data at that location has changed.
mutableData.Value = sceneLocks;
return TransactionResult.Success(mutableData);
}
static public void AddSceneLock()
{
Debug.Log("Attempting to add scene lock to database.");
DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("SceneLocks");
Debug.Log("Running Transaction...");
// Use a transaction to ensure that we do not encounter issues with
// simultaneous updates that otherwise might create more than MaxScores top scores.
reference.RunTransaction(SceneLockTransaction)
.ContinueWith(task => {
if (task.Exception != null)
{
Debug.Log(task.Exception.ToString());
}
else if (task.IsCompleted)
{
Debug.Log("Transaction complete.");
}
});
}
static public void RemoveSceneLock()
{
Debug.Log("Attempting to add scene lock to database.");
DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("SceneLocks");
Debug.Log("Running Transaction...");
// Use a transaction to ensure that we do not encounter issues with
// simultaneous updates that otherwise might create more than MaxScores top scores.
reference.RunTransaction(SceneUnlockTransaction)
.ContinueWith(task => {
if (task.Exception != null)
{
Debug.Log(task.Exception.ToString());
}
else if (task.IsCompleted)
{
Debug.Log("Transaction complete.");
}
});
}
[MenuItem("CONTEXT/SceneAsset/Lock Scene", false, 0)]
public static void LockScene()
{
Debug.Log("LockScene Called for scene " + sceneName + ".");
AddSceneLock();
}
[MenuItem("CONTEXT/SceneAsset/Unlock Scene", false, 0)]
public static void UnlockScene()
{
Debug.Log("UnlockScene Called for scene " + sceneName + ".");
RemoveSceneLock();
}
}
The errors always come from this line:
FirebaseDatabase.DefaultInstance.GetReference("SceneLocks");
Any line that has to do with "FirebaseDatabase.DefaultInstance" will throw one of the following two errors
Error 1:
InvalidOperationException: SyncContext not initialized.
Firebase.Unity.UnitySynchronizationContext.get_Instance ()
Firebase.Platform.PlatformInformation.get_SynchronizationContext ()
Firebase.FirebaseApp.get_ThreadSynchronizationContext ()
Firebase.Database.DotNet.DotNetPlatform+SynchronizationContextTarget..ctor ()
Firebase.Database.DotNet.DotNetPlatform.NewEventTarget (Firebase.Database.Internal.Core.Context c)
Firebase.Database.Internal.Core.Context.EnsureEventTarget ()
Firebase.Database.Internal.Core.Context.InitServices ()
Firebase.Database.Internal.Core.Context.Freeze ()
Firebase.Database.Internal.Core.RepoManager.CreateLocalRepo (Firebase.Database.Internal.Core.Context ctx, Firebase.Database.Internal.Core.RepoInfo info, Firebase.Database.FirebaseDatabase firebaseDatabase)
Firebase.Database.Internal.Core.RepoManager.CreateRepo (Firebase.Database.Internal.Core.Context ctx, Firebase.Database.Internal.Core.RepoInfo info, Firebase.Database.FirebaseDatabase firebaseDatabase)
Firebase.Database.FirebaseDatabase.EnsureRepo ()
Firebase.Database.FirebaseDatabase.get_RootReference ()
SceneLockingEditor.OnInspectorGUI () (at Assets/Bitloft/SCRIPTS/Editor/SceneLockingEditor.cs:37)
UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor[] editors, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1242)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
Error 2:
Exception: Custom Run loops are not supported!
Firebase.Database.Internal.Core.Context.GetExecutorService ()
Firebase.Database.Internal.Core.Context.GetConnectionContext ()
Firebase.Database.Internal.Core.Context.NewPersistentConnection (Firebase.Database.Internal.Connection.HostInfo info, IDelegate delegate_)
Firebase.Database.Internal.Core.Repo..ctor (Firebase.Database.Internal.Core.RepoInfo repoInfo, Firebase.Database.Internal.Core.Context ctx, Firebase.Database.FirebaseDatabase firebaseDatabase)
Firebase.Database.Internal.Core.RepoManager.CreateLocalRepo (Firebase.Database.Internal.Core.Context ctx, Firebase.Database.Internal.Core.RepoInfo info, Firebase.Database.FirebaseDatabase firebaseDatabase)
Firebase.Database.Internal.Core.RepoManager.CreateRepo (Firebase.Database.Internal.Core.Context ctx, Firebase.Database.Internal.Core.RepoInfo info, Firebase.Database.FirebaseDatabase firebaseDatabase)
Firebase.Database.FirebaseDatabase.EnsureRepo ()
Firebase.Database.FirebaseDatabase.get_RootReference ()
SceneLockingEditor.OnInspectorGUI () (at Assets/Bitloft/SCRIPTS/Editor/SceneLockingEditor.cs:37)
UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor[] editors, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1242)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
It's always one error or the other, and I can't determine what causes one error to appear rather than the other. Both errors stop whatever operation I'm trying to do on the database, which means I can't interact with my database at all.
I've taken a look at the quickstart projects and watched some videos of people setting up Firebase to work with their projects, and I can't seem to determine what I have messed up during the process. I have imported my google-services.json into the unity project. The quickstart projects worked just fine interacting with my database. It's just this particular script that won't work. I cannot find any mention of these two errors anywhere on Google. I even contacted the official Firebase support and they couldn't give me any advice on what the errors mean or what could be causing them.
I considered one problem might be in my initialization function. Instead of doing:
FirebaseApp app = FirebaseApp.DefaultInstance;
I figured that maybe I am supposed to use FirebaseApp.Create() with a custom name passed in, but that resulted in the same errors being thrown on the same line. I am at a loss for how to proceed with this problem. I don't know of anyone else who has had these particular errors, and I've done very much experimentation with different ways to access the database over the past several days. If anybody has an idea of what I am doing wrong here, or what causes these errors (and, how to fix them), I would really appreciate it.
At first you should initialize firebase with new instance of FirebaseApp with unique name. I do it like this:
FirebaseApp firebaseApp = FirebaseApp.Create(
FirebaseApp.DefaultInstance.Options,
"FIREBASE_EDITOR");
The second is setup references (DatabaseReference, StorageReference etc.) with this firebaseApp instance and use it only after FirebaseApp.CheckAndFixDependenciesAsync()
Overall code will look like this:
public static void Initialize(bool isEditor = false)
{
if (isEditor)
{
FirebaseApp firebaseApp = FirebaseApp.Create(
FirebaseApp.DefaultInstance.Options,
"FIREBASE_EDITOR");
firebaseApp.SetEditorDatabaseUrl("https://project.firebaseio.com/");
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
if (task.Result == DependencyStatus.Available)
{
database = FirebaseDatabase.GetInstance(firebaseApp).RootReference;
storage = FirebaseStorage.GetInstance(firebaseApp).RootReference;
auth = FirebaseAuth.GetAuth(firebaseApp);
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + task.Result);
}
});
}
else
{
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://project.firebaseio.com/");
database = FirebaseDatabase.DefaultInstance.RootReference;
storage = FirebaseStorage.DefaultInstance.RootReference;
auth = FirebaseAuth.DefaultInstance;
}
IsInitialized = true;
}
I had the same errors. I spent several hours solving this and it worked for me

CodenameOne filter optimization on set of containers

In my app, I have a searchbox which allows users to filter as they type. For some reason I can't get an InfinteProgress to properly display while the filtering is being executed.
Here's my code:
Pass 1
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
Display.getInstance().invokeAndBlock(new Runnable() {
#Override
public void run() {
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
Display.getInstance().callSerially(new Runnable() {
#Override
public void run() {
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
});
}
});
}
In this version, the infinite progress shows up in the proper position, but it doesn't spin.
Pass 2
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
}
}
In this version, the magnifier icon just flashes briefly, but the InfiniteProgress spinner is never visible.
I get the same results on the simulator and on an Android device.
How can I get the InfiniteProgress to spin while the search is taking place?
invokeAndBlock opens a new thread and thus violates the EDT as you access UI components on a separate thread.
Try using callSerially instead to postpone the following code into the next EDT cycle although I'm not sure that will help as everything is still happening on the EDT.
Alternatively I'm guessing the method isVisible takes time, so you can enclose that call alone in invokeAndBlock.
To understand invokeAndBlock check out the developer guide https://www.codenameone.com/manual/edt.html

android 23 uri permission denial

i have a code that doing the following:
i got READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE in manifest
i m getting photos uri from phone you choose and put it into fragment and insert into viewpager.
it works fine on sdk 22 below.
but as on android 23 it keep on saying
permission denial java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovioder.MediaContentProvider from ProcessRecord
which is refer to my code on line in fragment page
/*********************
bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, option);
which i put inside reSize() method
**********************/
i have trying to read develop console documents and notice we need to check permission and ask user for it.
my questions is
1. which permission should i ask, i have tried READ and WRITE
2. where should i surround the check permission for, it is outside the method? or just surround the line.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int hasPermission = checkSelfPermission(context,
Manifest.permission.READ_EXTERNAL_STORAGE);
if (hasPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
RESULT_PERMS_INITIAL);
} else {
bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, option);
}
} else {
bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, option);
}
and on request for result
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
if (requestCode == RESULT_PERMS_INITIAL) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
bitmap = resizeBitmap(uri, getActivity().getApplicationContext());
}
else {
Toast.makeText(context, "error", Toast.LENGTH_SHORT).show();
}
}
else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
For API-23 Android introduced new permission types. You should read this.
For the example please follow these page
RuntimePermissionsBasic
RuntimePermissions
I hope, it will work for you.

Resources