how do i remove uri path information? - java

I have requirement like i need to deleted selected file information if anybody selected wrong file, but after call delete() method its deleted from gallery also,
my question is how can remove selected file URI information i dont want to delete selected file form gallery, any help?

Working with Android Architecture Components, such as: View Model, LiveData, etc. I would like to suggest you to follow Official Guide from Android.
When using Android Architecture Components to call a API request, how I try to achieve my goal is as follow:
Create one Repo class, in that class, initialize the Retrofit Interface(if using Retrofit). Create a function that calls the required API, handle request response and returns a Live Data. Make extra functions for the parameter to be passed with URL.
Create one View Model class, in that class, initialize above Repo class. Create a function that calls repo class function which returns Live Data and this function also returns LiveData. Make extra functions for the parameter to be passed to Repo for adding with URL.
In your View class (Activity/Fragment), initialize View Model class and pass those parameters which are required URL params. Call the View Model function, which returns Live Data and observe that in your View class.
You will get data in your View Class when any change appears in Live Data.
Above is a simple practice, but it can be made good by making responses generic according to your requirement.

You can create public function in VM and pass desired paramas to it and then invoke desired URL from repo .
Refer example
https://github.com/googlesamples/android-architecture-components/blob/master/BasicSample/app/src/main/java/com/example/android/persistence/viewmodel/ProductListViewModel.java

you can call some public method from viewmodel and then pass params to it.somehow like this
viewmodel
class UserViewmodel: ViewModel() {
fun callApi(userId: String) : Any {
// Your method definition
return result
}
}
and in activity / fragment call method via viewmodel instance
class UserActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user)
val viewModel = ViewModelProviders.of(this).get(UserViewmodel::class.java)
val result = viewModel.callApi("userId")
}
}

Related

MVVM shared prefs in a remote class

So I'm implementing my first Android project with the MVVM pattern by following the official Android docs schema (below) and other internet resources.
In another activity I used a PreferenceFragmentCompat to save some user settings. Now I need those settings in a Remote data source class, but without the context I can't access the Shared Prefs.
Any suggestion on how to accomplish that?
P.S. I'm using Java...
From their documentation (https://developer.android.com/reference/androidx/preference/PreferenceFragmentCompat)
To retrieve an instance of SharedPreferences that the preference hierarchy in this fragment will use by default, call PreferenceManager.getDefaultSharedPreferences(android.content.Context) with a context in the same package as this fragment.
I don't believe this is referring to the exact package the file is in, but the overall top level package of your source files. As I am able break out my fragments/activities in different packages from the one where my PreferenceFragmentCompat is located in and able to retrieve the stored settings.
I wouldn't advise passing in the fragment/activity context to your Remote Data Source class, but if you have dagger setup you could inject an instance of PreferenceManager class created from app context through the constructor and fetch whatever settings you need. Or, you can pass those settings that your data source requires from your view -> vm -> repository/data source.
Using the MVVM with repository pattern (your data source class) I would do something like the following:
1.) Create a ViewModel which holds an instance of your data source/repository class.
2.) From your view (activity/fragment), obtain an instance of PreferenceManager and fetch the settings you need.
3.) Pass them along to your viewModel which then passes it along to your data source/repository.
4.) Do whatever you need in your data source class with those settings
... inside your view class
val pref = PreferenceManager.getDefaultSharedPreferences(context).getString(PREF_KEY_NAME, null)
viewModel.yourMethod(pref)
... inside your viewmodel class
fun yourMethod(pref: String?) {
repository.doSomething(pref)
}
... inside your repository/data source class
fun doSomething(pref: String?) {
// whatever you need to do with this pref.
// e.g. api call
api.doMethod(pref)
}
You can have an interface PreferenceStorage and inject it into your RemoteDataSource. You can test your remote data source with a mock preference storage.
Here is the example from Google I\O app:
https://github.com/google/iosched/blob/master/shared/src/main/java/com/google/samples/apps/iosched/shared/data/prefs/PreferenceStorage.kt
In Kotlin
class RemoteDataSource #Inject constructor(private val preferenceStorage: PreferenceStorage) {
...
}

FirebaseInstanceIdService does not exist

I'm creating a chat app and according to the tutorial I should create this:
Tutorial example
The problem is that nowadays this function (FirebaseInstanceIdService) no longer exists and therefore I cannot use it.
Would anyone advise me with what code to achieve the same result?
Thank you
FirebaseInstanceIdService has been depracated and replaced with FirebaseMessagingService
https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceIdService
onTokenRefresh is now onNewToken.
Within the class extending FirebaseMessagingService, in which you are already overriding onMessageReceived() method, override the onNewToken(token: String) method (this replaces the old onTokenRefresh(), so all the logic you had there, must be put here).
With Kotlin,
override fun onMessageReceived(remoteMessage: RemoteMessage) {
//the logic here
}
override fun onNewToken(token: String) {
//all the logic of the old FirebaseInstanceIdService.onTokenRefresh() here
//usually, to send to the app server the instance ID token
sendTokenToTheAppServer(token)
}

Overriding ViewModelStore

Is it possible to provide once own implementation of a ViewModelStore for ViewModelProviders to use instead of the default one?
More precisely, I'm interested in adding fun clear(vm: ViewModel) (or using an index or something similar) functionality to the ViewModelStore so that I can clear a single view model of my choice, not just use the built in ViewModelStore#clear:
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.onCleared();
}
mMap.clear();
}
which clears all view models.
First, I think you should not consider doing that, because that's an implementation detail of Architecture Components library. Most possibly you should come up with a better solution as a result of adapting your use-case to match guidelines/contracts exposed by ViewModels API.
Nevertheless, let's examine possibilities of doing that.
Here's the code, that we should use in order to obtain a ViewModel implementation:
val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
What will this code result in, is that it will create an instance of HolderFragment, which is a retained fragment, and will attach it to this's fragment manager (might be either FragmentActivity's fragment manager or Fragment's child fragment manager).
This HolderFragment will be added with a HolderFragment.HOLDER_TAG, thus we are able to get an instance of this fragment from the fragment manager.
val holderFragment = supportFragmentManager.findFragmentByTag("android.arch.lifecycle.state.StateProviderHolderFragment") as HolderFragment
It's the HolderFragment, that creates an instance of ViewModelStore and keeps that instance as a private field. There exists a getter for that field, but there does not exist a setter, which means, that the only way to "substitute" this object is by using reflection.
But before doing that, let's try to write a custom implementation of ViewModelStore class:
class MyViewModelStore : ViewModelStore() {
private val mMap = HashMap<String, ViewModel>()
internal fun put(key: String, viewModel: ViewModel) {
val oldViewModel = mMap.put(key, viewModel)
oldViewModel?.onCleared() // COMPILATION ERROR -> Cannot access 'onCleared': it is protected/*protected and package*/ in 'ViewModel'
}
internal operator fun get(key: String): ViewModel? {
return mMap[key]
}
override fun clear() {
for (vm in mMap.values) {
vm.onCleared() // COMPILATION ERROR -> Cannot access 'onCleared': it is protected/*protected and package*/ in 'ViewModel'
}
mMap.clear()
}
}
Unfortunately, we cannot do that, because ViewModel#onCleared() has a protected package access, which makes impossible for us call it outside of the android.arch.lifecycle package. Again, we can use reflection to do that (but how good is that?).
Despite being not advised (by me), seems like that's also not achievable to do (without using reflection).

Play framework: how to pass parameters extracted in the onRequest function

I overwrote the public Action onRequest(final Http.Request request, Method method) method to check that the mandatory http headers are passed in and valid, i.e.: I extract the apiKey (and other things) and make sure that these are valid (that there's data associated with the apiKey). Then I call return super.onRequest(request, method); and I end up in my controller where I once again have to extract the apiKey and get the associated data from the DB.
Is there a way to pass in the data to my controller's method (for instance: public static Result addUser() ).
Thank you.
I know this question is for Java, but I work with Play in Scala, and this question is more related to Play then it is to Java
In Scala I am able to extend WrappedRequest to make my own custom request type, that has instance variables I want to access in my controller:
// Scala code
case class MyRequest[A](request: Request[A]) extends WrappedRequest(request) {
// This is a public instance variable
val apiKey = request.headers.get("Authorization)
}
Then later on in my controller I can access the action object which now has the type of MyRequest:
// Scala code
def foobar(action: MyRequest[AnyContent]) = Action {
// Do something with the api key
val apiKey = action.apiKey
// Send back a response
Ok("foobar")
}
In Java it looks like you can do something similar using a Wrapped Context

Using "Adapter" pattern

How I understand, the Goal of the Adapter pattern is to call some class methods using some interface (which opened to clients). To make adapter pattern we need to implement some interface (which uses by client), and also we need to extend some class, which methods client need to call when calling interface methods.
class Adapter extends NeedClass implements PublicInterface{}
But what if we haven't interface, but have only 2 classes? For example we have some class(not interface!) which methods uses clients. Now we need to call methods of other class by making adapter class, but we cant to do this, because we cant make multiple Inheritance on the adapter class.
class Adapter extends NeedClass, PublicInterface
above code doesnt work.
What we can do in this case?
You can has an instance of NeedClass in Adapter and call it, when you need. So you extend only from PublicInterface.
public class Adapter extends PublicInterface {
private NeedClass needClass;
#Override
public void doSomething() {
needClass.doSomethingElse("someParameter");
}
}
You can use a composition instead of inheritance. Add a field to Adapter class of type NeedClass:
public class Adapter extends PublicInterface {
private NeedClass needClass;
}
Then inside Adapter methods delegate execution to needClass field.
From what i have understood the Adapter Pattern.
it is helpful when dealing with the third part codes such as API which is/ are subject to changes any time and my likely to break your code if implemented direct.
For example : Using Paypal in your site for payment online.let's assume the Paypal uses the method payMoney() for payment. and after sometime they decide to change the method to something else let's say sendMoney(). This is likely to break your code if implemented directly, with the use of Adapter Design pattern this can be solves as follow
the third part code => Paypal
class Paypal {
public function __construct(){
// their codes
}
public function payMoney($amount){
// the logic of validating
// the $amount variables and do the payment
}
}
so implement it directly in the code as below will break the code
$pay = new Paypal();
$pay->payMoney(200);
using adapter will save numbers of hours and a complex work of updating the code from payMoney() to sendMoney() in every where that the API scripts has been implemented. Adapter enable update in one place and that's it.
Let see it.
class paypalAdapter {
private $paypal;
// Paypal object into construct and check if it's pa
// Paypal object via type hint
public function __construct(PayPal $paypal) {
$this->paypal = $paypal;
}
// call the Paypal method in your own
//custom method that is to be
// implemented directly into your code
public function pay($amount) {
$this->paypal->payMoney($amount);
}
}
so it is like that and there you can go and use the PaypalAdater directly into the code as follow;
$pay = new PaypalAdapter(new Paypal);
$pay->pay(200);
So in future when the Vendor(Paypal) decide to use sendMoney instead of payMoney what to be done is to open the PaypalAdapter class and do the following in the pay($amount) method:
// SEE THIS METHOD ABOVE TO OBSERVE CHANGES
// FROM $this->paypal->payMoney($amount);
// TO $this->paypal->senMoney($amount);
public function pay($amount) {
$this->paypal->sendMoney($amount);
}
After this minor change in one place, everything works well as before.

Categories