7

I'm working on a library which will provide fragment with some input fields in it. These input fields will contain user's private information that app which uses my library should not have access to. Therefore edittexts or we can say fragment's layout cannot be accessed from activity(findViewById,getChildAt..) where this fragment is attached to.

Usage of dialog, or another activity is not acceptable, this fragment should be included directly in activity's layout.

Is this even possible in Android ?

I was thinking of creating views dynamically, and overriding methods such as getChildAt to prevent access to child views, but before I start "playing" with this problem, I'd rather ask here for some opinions.

Palejandro
  • 2,092
  • 5
  • 26
  • 38
  • 1
    The only idea I have is to have TextWatchers at your EditTexts, which will make some on-the-fly encryption of entered data. And store real private data somewhere at Keystore system, for example. But don't know how to implement this :) – Goltsev Eugene Apr 15 '16 at 05:37
  • @GoltsevEugene using encryption isn't bad idea, good point. – Palejandro Apr 15 '16 at 17:50
  • You can disable the touch event for all your views & Override getView method of Fragment and return null. So that no one can get your Fragment view using this method... thats what i am thinkig .... – Moinkhan Apr 20 '16 at 13:53

6 Answers6

3

Android does not provide a model for such a usage. Overriding methods will certainly make it harder to access these views, but not impossible. Your custom view class has to store its children somewhere. Even if that is a private field, reflection can access it.

An activity has full control over his content, and I don't think you can prevent that.

F43nd1r
  • 7,690
  • 3
  • 24
  • 62
  • yes, you are right, Android isn't build for such a thing, but I was curious if someone came across this problem. I suppose, if there is an answer to this problem, it won't be easy to implement :( . (Lots of overriding, encrypting). I'll wait few more days for another opinions.. – Palejandro Apr 15 '16 at 18:00
2

First of all what you want is not a good approach, and what i am suggesting is just an idea, its not tested and recommended but can do your work

Create class BaseFragment and extend you each class with Base Fragment must override its getView()

In these approached you have to remove root view as a class member getView returns the same

public class BaseFragment extends Fragment {

    @Nullable
    @Override
    public View getView() {
     super.getView();
    }
}

Now you can do it in two ways

Create boolean in BaseFragment with private access boolean canAccess = true; with no getter and setter and change definition of your getView() to

public BaseFragment() {
    canAccess = false;
}

@Nullable
@Override
public View getView() {
    if(canAccess)
        return super.getView();
    return 
        null;
}

You must call super() for your every child constructors, now if you access getView inside the class canAccess is true so you will get actual view otherwise you will get null.

As per documentation

Get the root view for the fragment's layout (the one returned by {@link #onCreateView}),

if provided @return The fragment's root view, or null if it has no layout.

Second option is much simplest

@Nullable
@Override
public View getView() {
    try {
        throw new Exception("Who called me?");
    } catch (Exception e) {
        String className = e.getStackTrace()[1].getClass().getCanonicalName();
        if (className.equals(YourParentActivity.class.getCanonicalName()))
            return null;
        else
            return super.getView();
    }
}
Community
  • 1
  • 1
Haris Qurashi
  • 2,104
  • 1
  • 13
  • 28
2

You can disable contents inside your fragment using following method:

public void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) {
    int childCount = viewGroup.getChildCount();
    for(int i = 0; i < childCount; i++) {
        View view = viewGroup.getChildAt(i);
        view.setEnabled(enabled);
        if (view instanceof ViewGroup) {
            enableDisableViewGroup((ViewGroup) view, enabled);
        }
    }
}

You can simply call above method as follows:

enableDisableViewGroup((ViewGroup) rootView, true); // disable

enableDisableViewGroup((ViewGroup) rootView, false); // enable

This method will work for both fragments and adapters to disable/enable their contents.

zeeali
  • 1,524
  • 20
  • 31
0

I did not understand it correctly I guess, but I think that anything created by private access mode cannot be accessed from outside.

ozo
  • 763
  • 7
  • 13
0

Did you ever consider using webview for your particular problem !!!

make a fragment and in it show your desired webview and let user input anything he likes.

by this the OTHER APP wont have access to the EditTexts.

Omid Heshmatinia
  • 5,089
  • 2
  • 35
  • 50
  • Yes I also considered this option, but webview can be accessed from outside and that means it's content too.. – Palejandro Apr 18 '16 at 16:56
0

You can override TextView's getText() and return null for private views. If someone will get this text view - he will not be able to get it's content.

Wackaloon
  • 2,285
  • 1
  • 16
  • 33