Я получаю следующую ошибку от FileProvider.getUriForFile
java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.content.res.Resources android.content.Context.getResource ()' для ссылки на пустой объект
Однако, когда я отображаю context.toString()
, я получаю это, которое (я думаю) доказывает, что объект не является нулевым:
uk.co.letsdelight.letsdelight.MainActivity@8eec139
Код записывает Completed download of update file
в logcat, но не записывает URI successfully set
на устройстве API 24. Он работает на API 23. Вот важная часть кода. Класс Update
вызывается из MainActivity
с new Update(status, message).check(this);
public class Update extends Activity {
private File outputFile;
private TextView status;
private TextView message;
private String TAG = "LETSDELIGHT";
public Update(TextView status){
this.status = status;
}
public Update(TextView status, TextView message){
this.status = status;
this.message = message;
}
public void check(final Context c) {
status.setText("Checking for updates");
// Check for updates and give user option to update
// UPDATE button pressed
UpdateApp updateApp = new UpdateApp();
updateApp.setContext(c);
updateApp.execute(c.getString(R.string.apk_uri));
status.setText("Downloading update");
}
public class UpdateApp extends AsyncTask<String,Void,Void> {
private Context context;
private Throwable thrown = null;
private String statusMessage;
public void setContext(Context contextf){
context = contextf;
}
@Override
protected Void doInBackground(String... arg0) {
try {
URL url = new URL(arg0[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.connect();
Log.i(TAG,"Starting download of update file");
statusMessage = "Starting download of update file";
File file = context.getCacheDir();
file.mkdirs();
outputFile = new File(file, "update.apk");
if(outputFile.exists()){
outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = conn.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
outputFile.setReadable(true, false);
Log.i(TAG, "Completed download of update file");
statusMessage = "Completed download of update file";
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(context, getString(R.string.file_provider_authority), outputFile);
} else {
uri = Uri.fromFile(outputFile);
}
Log.i(TAG, "URI successfully set");
statusMessage = "URI successfully set";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (Throwable ex) {
Log.e(TAG, ex.toString());
thrown = ex;
}
return null;
}
@Override
protected void onPostExecute(Void v) {
status.setText("");
if (statusMessage != null) {
status.setText(statusMessage);
}
if (thrown != null) {
status.setText(context.toString());
message.setText(thrown.toString());
}
outputFile.delete();
super.onPostExecute(v);
}
}
}
Файл AndroidManifest.xml
содержит следующую запись:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="@strings/file_provider_authority"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
file_provider_paths.xml
выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="cache" path="."/>
</paths>
Я попытался изменить context
на getApplication()
и getApplicationContext()
, что привело к NullPointerException
, но с немного другой формулировкой ресурса.
Что еще я могу попытаться решить эту проблему?
EDIT:
Я изменил код, чтобы попытаться добраться до сути проблемы:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
statusMessage = "Context is: " + context.getString(R.string.file_provider_authority);
uri = FileProvider.getUriForFile(context, context.getString(R.string.file_provider_authority), outputFile);
statusMessage = "uri set";
} else {
uri = Uri.fromFile(outputFile);
}
statusMessage
устанавливается для отображения правильной строки Полномочия провайдера. Не устанавливается значение "URI Set". Поэтому это определенно FileProvider.getUriForFile()
, который терпит неудачу.
Учитывая, что context
не равно нулю, а Authority - правильная строка, что еще может вызвать ошибку здесь?