Fix richiesta permessi e implementazione del nuovo download degli aggiornamenti dell'app
This commit is contained in:
parent
39068ba1d5
commit
c118a87f88
@ -6,6 +6,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
@ -66,6 +67,17 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name=".core.update.GenericFileProvider"
|
||||||
|
android:authorities="${applicationId}.core.update.GenericFileProvider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/provider_paths"/>
|
||||||
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -12,6 +12,8 @@ import androidx.appcompat.app.ActionBarDrawerToggle;
|
|||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.SearchView;
|
import androidx.appcompat.widget.SearchView;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
|
import android.os.StrictMode;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -53,7 +55,7 @@ public class MainActivity extends AppCompatActivity
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
//ExceptionsHandler.init(this);
|
|
||||||
|
|
||||||
mBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.activity_main, null, false);
|
mBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.activity_main, null, false);
|
||||||
setContentView(mBinding.getRoot());
|
setContentView(mBinding.getRoot());
|
||||||
@ -80,9 +82,9 @@ public class MainActivity extends AppCompatActivity
|
|||||||
|
|
||||||
|
|
||||||
private void startLoginActivity(){
|
private void startLoginActivity(){
|
||||||
|
this.finish();
|
||||||
Intent myIntent = new Intent(this, LoginActivity.class);
|
Intent myIntent = new Intent(this, LoginActivity.class);
|
||||||
startActivity(myIntent);
|
startActivity(myIntent);
|
||||||
this.finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import android.content.Intent;
|
|||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.app.Activity;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@ -31,13 +29,17 @@ public class SplashActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
initAppVersion();
|
initAppVersion();
|
||||||
|
|
||||||
|
|
||||||
PermissionsHelper.askPermissions(this, () -> {
|
PermissionsHelper.askPermissions(this, () -> {
|
||||||
init();
|
init();
|
||||||
}, permanentlyDenied -> {
|
}, permanentlyDenied -> {
|
||||||
if(permanentlyDenied) {
|
if(permanentlyDenied) {
|
||||||
DialogSimpleMessageHelper.makeErrorDialog(this,
|
DialogSimpleMessageHelper.makeErrorDialog(this,
|
||||||
new SpannableString(getText(R.string.permissions_permanrntly_denied)), null, () -> {
|
new SpannableString(getText(R.string.permissions_permanently_denied)), null, () -> {
|
||||||
|
this.finish();
|
||||||
|
}).show();
|
||||||
|
} else {
|
||||||
|
DialogSimpleMessageHelper.makeErrorDialog(this,
|
||||||
|
new SpannableString(getText(R.string.permissions_denied)), null, () -> {
|
||||||
this.finish();
|
this.finish();
|
||||||
}).show();
|
}).show();
|
||||||
}
|
}
|
||||||
@ -71,19 +73,15 @@ public class SplashActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
|
|
||||||
private void startLoginActivity(){
|
private void startLoginActivity(){
|
||||||
|
this.finish();
|
||||||
Intent myIntent = new Intent(this, LoginActivity.class);
|
Intent myIntent = new Intent(this, LoginActivity.class);
|
||||||
startActivity(myIntent);
|
startActivity(myIntent);
|
||||||
this.finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startMainActivity(){
|
private void startMainActivity(){
|
||||||
new Handler().postDelayed(() -> {
|
this.finish();
|
||||||
Intent myIntent = new Intent(this, MainActivity.class);
|
Intent myIntent = new Intent(this, MainActivity.class);
|
||||||
startActivity(myIntent);
|
startActivity(myIntent);
|
||||||
this.finish();
|
|
||||||
}, 3000);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
package it.integry.integrywmsnative.core.update;
|
||||||
|
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
|
||||||
|
public class GenericFileProvider extends FileProvider {}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package it.integry.integrywmsnative.core.update;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class UpdateApp extends AsyncTask<String,Void,Void> {
|
||||||
|
private Context context;
|
||||||
|
public void setContext(Context contextf){
|
||||||
|
context = contextf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(String... arg0) {
|
||||||
|
try {
|
||||||
|
URL url = new URL(arg0[0]);
|
||||||
|
HttpURLConnection c = (HttpURLConnection) url.openConnection();
|
||||||
|
c.setRequestMethod("GET");
|
||||||
|
c.setDoOutput(true);
|
||||||
|
c.connect();
|
||||||
|
|
||||||
|
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||||
|
file.mkdirs();
|
||||||
|
File outputFile = new File(file, "update.apk");
|
||||||
|
if(outputFile.exists()){
|
||||||
|
outputFile.delete();
|
||||||
|
}
|
||||||
|
FileOutputStream fos = new FileOutputStream(outputFile);
|
||||||
|
|
||||||
|
InputStream is = c.getInputStream();
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int len1 = 0;
|
||||||
|
while ((len1 = is.read(buffer)) != -1) {
|
||||||
|
fos.write(buffer, 0, len1);
|
||||||
|
}
|
||||||
|
fos.close();
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setDataAndType(Uri.fromFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)), "application/vnd.android.package-archive");
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
|
||||||
|
context.startActivity(intent);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("UpdateAPP", "Update error! " + e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,21 +1,94 @@
|
|||||||
package it.integry.integrywmsnative.core.update;
|
package it.integry.integrywmsnative.core.update;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.DownloadManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
|
|
||||||
import com.github.javiersantos.appupdater.AppUpdater;
|
import com.github.javiersantos.appupdater.AppUpdater;
|
||||||
|
import com.github.javiersantos.appupdater.AppUpdaterUtils;
|
||||||
|
import com.github.javiersantos.appupdater.enums.AppUpdaterError;
|
||||||
import com.github.javiersantos.appupdater.enums.Display;
|
import com.github.javiersantos.appupdater.enums.Display;
|
||||||
import com.github.javiersantos.appupdater.enums.UpdateFrom;
|
import com.github.javiersantos.appupdater.enums.UpdateFrom;
|
||||||
|
import com.github.javiersantos.appupdater.objects.Update;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
import it.integry.integrywmsnative.R;
|
||||||
import it.integry.integrywmsnative.core.settings.SettingsManager;
|
import it.integry.integrywmsnative.core.settings.SettingsManager;
|
||||||
|
|
||||||
public class UpdatesManager {
|
public class UpdatesManager {
|
||||||
|
|
||||||
public static void init(Context context) {
|
public static void init(Activity context) {
|
||||||
|
String currentVersionUrl = "http://" + SettingsManager.i().server.host + ":" + SettingsManager.i().server.port + "/ems-api/wms/currentVersion";
|
||||||
|
String currentDownloadUrl = "http://" + SettingsManager.i().server.host + ":" + SettingsManager.i().server.port + "/ems-api/wms/android-release_v2.apk";
|
||||||
|
|
||||||
|
|
||||||
AppUpdater appUpdater = new AppUpdater(context)
|
AppUpdater appUpdater = new AppUpdater(context)
|
||||||
.setDisplay(Display.DIALOG)
|
.setDisplay(Display.DIALOG)
|
||||||
.setUpdateFrom(UpdateFrom.JSON)
|
.setUpdateFrom(UpdateFrom.JSON)
|
||||||
.setUpdateJSON("http://" + SettingsManager.i().server.host + ":" + SettingsManager.i().server.port + "/ems-api/wms/currentVersion");
|
.setUpdateJSON(currentVersionUrl)
|
||||||
|
.setButtonUpdateClickListener((dialog, which) -> {
|
||||||
|
|
||||||
|
installAPK(context, currentDownloadUrl);
|
||||||
|
});
|
||||||
appUpdater.start();
|
appUpdater.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void installAPK(Activity context, String downloadURL) {
|
||||||
|
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
|
||||||
|
String fileName = context.getResources().getString(R.string.app_name) + ".apk";
|
||||||
|
destination += fileName;
|
||||||
|
final Uri uri = Uri.parse("file://" + destination);
|
||||||
|
|
||||||
|
//Delete update file if exists
|
||||||
|
final File file = new File(destination);
|
||||||
|
if (file.exists())
|
||||||
|
file.delete();
|
||||||
|
|
||||||
|
//set downloadmanager
|
||||||
|
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadURL));
|
||||||
|
request.setDescription(context.getString(R.string.notification_update_download));
|
||||||
|
request.setTitle(context.getString(R.string.app_name));
|
||||||
|
|
||||||
|
//set destination
|
||||||
|
request.setDestinationUri(uri);
|
||||||
|
|
||||||
|
// get download service and enqueue file
|
||||||
|
final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||||
|
manager.enqueue(request);
|
||||||
|
|
||||||
|
//set BroadcastReceiver to install app when .apk is downloaded
|
||||||
|
BroadcastReceiver onComplete = new BroadcastReceiver() {
|
||||||
|
public void onReceive(Context ctxt, Intent i) {
|
||||||
|
|
||||||
|
Uri fileLoc;
|
||||||
|
Intent intent;
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
|
||||||
|
fileLoc = GenericFileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".core.update.GenericFileProvider", file);
|
||||||
|
} else {
|
||||||
|
intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
fileLoc = Uri.fromFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
intent.setDataAndType(fileLoc, "application/vnd.android.package-archive");
|
||||||
|
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//register receiver for when .apk download is compete
|
||||||
|
context.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
package it.integry.integrywmsnative.core.utility;
|
package it.integry.integrywmsnative.core.utility;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.os.Build;
|
||||||
|
|
||||||
import com.emreeran.permissionlivedata.PermissionLiveData;
|
import com.emreeran.permissionlivedata.PermissionLiveData;
|
||||||
import com.emreeran.permissionlivedata.Status;
|
import com.emreeran.permissionlivedata.Status;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
|
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
|
||||||
@ -15,26 +17,62 @@ public class PermissionsHelper {
|
|||||||
|
|
||||||
public static void askPermissions(AppCompatActivity activity, Runnable onPermissionsConfirmed, RunnableArgs<Boolean> onPermissionsDenied) {
|
public static void askPermissions(AppCompatActivity activity, Runnable onPermissionsConfirmed, RunnableArgs<Boolean> onPermissionsDenied) {
|
||||||
|
|
||||||
PermissionLiveData permissionLiveData = PermissionLiveData.create(
|
List<String> permissionsToAsk = new ArrayList<>();
|
||||||
activity,
|
permissionsToAsk.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
permissionsToAsk.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
permissionsToAsk.add(Manifest.permission.INTERNET);
|
||||||
);
|
permissionsToAsk.add(Manifest.permission.ACCESS_WIFI_STATE);
|
||||||
|
|
||||||
permissionLiveData.observe(activity, permission -> {
|
|
||||||
if (permission.getStatus() == Status.RECEIVED) {
|
if(Build.VERSION.SDK_INT >= 23) {
|
||||||
if (permission.getGranted()) {
|
//permissionsToAsk.add(Manifest.permission.REQUEST_INSTALL_PACKAGES);
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] permissionArray = new String[permissionsToAsk.size()];
|
||||||
|
permissionsToAsk.toArray(permissionArray);
|
||||||
|
|
||||||
|
PermissionLiveData permissionLiveData = PermissionLiveData.create(
|
||||||
|
activity, permissionArray);
|
||||||
|
|
||||||
|
AtomicInteger permissionStatusCounter = new AtomicInteger();
|
||||||
|
AtomicInteger permissionGrantedCounter = new AtomicInteger();
|
||||||
|
AtomicInteger permissionPendingCounter = new AtomicInteger();
|
||||||
|
AtomicInteger permissionDeniedCounter = new AtomicInteger();
|
||||||
|
AtomicInteger permissionPermDeniedCounter = new AtomicInteger();
|
||||||
|
|
||||||
|
Runnable checkPermissionIfDone = () -> {
|
||||||
|
if(permissionStatusCounter.get() == permissionArray.length){
|
||||||
|
|
||||||
|
if(permissionGrantedCounter.get() == permissionStatusCounter.get()) {
|
||||||
onPermissionsConfirmed.run();
|
onPermissionsConfirmed.run();
|
||||||
//UtilityToast.showToast("Permission " + permission.getName() + " was granted.");
|
} else if(permissionPendingCounter.get() > 0) {
|
||||||
} else if (permission.getShouldShowRequestPermissionRationale()) {
|
onPermissionsDenied.run(false);
|
||||||
|
} else if(permissionPermDeniedCounter.get() > 0) {
|
||||||
onPermissionsDenied.run(true);
|
onPermissionsDenied.run(true);
|
||||||
//UtilityToast.showToast("Permission " + permission.getName() + " was denied without ask never again checked.");
|
|
||||||
} else {
|
} else {
|
||||||
onPermissionsDenied.run(false);
|
onPermissionsDenied.run(false);
|
||||||
//UtilityToast.showToast("Permission " + permission.getName() + " was denied.");
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
permissionLiveData.observe(activity, permission -> {
|
||||||
|
|
||||||
|
permissionStatusCounter.getAndIncrement();
|
||||||
|
|
||||||
|
if (permission.getStatus() == Status.RECEIVED) {
|
||||||
|
if (permission.getGranted()) {
|
||||||
|
permissionGrantedCounter.getAndIncrement();
|
||||||
|
checkPermissionIfDone.run();
|
||||||
|
} else if (permission.getShouldShowRequestPermissionRationale()) {
|
||||||
|
permissionPermDeniedCounter.getAndIncrement();
|
||||||
|
checkPermissionIfDone.run();
|
||||||
|
} else {
|
||||||
|
permissionDeniedCounter.getAndIncrement();
|
||||||
|
checkPermissionIfDone.run();
|
||||||
}
|
}
|
||||||
} else if (permission.getStatus() == Status.PENDING) {
|
} else if (permission.getStatus() == Status.PENDING) {
|
||||||
//UtilityToast.showToast(String.format("Pending request for %s", permission.getName()));
|
permissionPendingCounter.getAndIncrement();
|
||||||
|
checkPermissionIfDone.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -233,13 +233,12 @@ public class LoginViewModel {
|
|||||||
public void onLoginCompleted() {
|
public void onLoginCompleted() {
|
||||||
loginButtonEnabled.set(true);
|
loginButtonEnabled.set(true);
|
||||||
|
|
||||||
|
|
||||||
SettingsManager.update();
|
SettingsManager.update();
|
||||||
|
|
||||||
|
mActivity.finish();
|
||||||
|
|
||||||
Intent myIntent = new Intent(mActivity, MainActivity.class);
|
Intent myIntent = new Intent(mActivity, MainActivity.class);
|
||||||
mActivity.startActivity(myIntent);
|
mActivity.startActivity(myIntent);
|
||||||
|
|
||||||
mActivity.finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -163,6 +163,8 @@
|
|||||||
|
|
||||||
<string name="level">Livello</string>
|
<string name="level">Livello</string>
|
||||||
<string name="not_valid">Non valido</string>
|
<string name="not_valid">Non valido</string>
|
||||||
<string name="permissions_permanrntly_denied"><![CDATA[Sono stati negati tutti i permessi necessari al funzionamento dell\'applicazione. L\'applicazione verrà adesso chiusa.]]></string>
|
<string name="permissions_permanently_denied"><![CDATA[Sono stati negati tutti i permessi necessari al funzionamento dell\'applicazione. L\'applicazione verrà adesso chiusa.]]></string>
|
||||||
|
<string name="permissions_denied">Tutti i permessi sono stati declinati, riapri l\'applicazione per continuare.</string>
|
||||||
|
<string name="notification_update_download">Download aggiornamento</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@ -171,6 +171,8 @@
|
|||||||
<string name="too_much_lu_found_message">Multiple LU found</string>
|
<string name="too_much_lu_found_message">Multiple LU found</string>
|
||||||
<string name="ask_print_message">Do you want print the label?</string>
|
<string name="ask_print_message">Do you want print the label?</string>
|
||||||
<string name="ask_position_of_lu_message">Please scan a <b>Position</b> barcode</string>
|
<string name="ask_position_of_lu_message">Please scan a <b>Position</b> barcode</string>
|
||||||
<string name="permissions_permanrntly_denied">Please note that all permissions are required. Application will close now.</string>
|
<string name="permissions_permanently_denied">Please note that all permissions are required. Application will close now.</string>
|
||||||
|
<string name="permissions_denied">All permissions are required, please reopen the app.</string>
|
||||||
|
<string name="notification_update_download">Downloading update</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
4
app/src/main/res/xml/provider_paths.xml
Normal file
4
app/src/main/res/xml/provider_paths.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<external-path name="external_files" path="."/>
|
||||||
|
</paths>
|
||||||
Loading…
x
Reference in New Issue
Block a user