[英]FileProvider.getUriForFile context throwing NullPointer exeption
I am getting the following error from FileProvider.getUriForFile
我从
FileProvider.getUriForFile
得到以下错误
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResource()' on a null object reference
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'android.content.res.Resources android.content.Context.getResource()'
However, when I display context.toString()
I get this which (I think) proves that the object is not null: 但是,当我显示
context.toString()
我得到了这个(我认为)证明该对象不是null:
uk.co.letsdelight.letsdelight.MainActivity@8eec139
uk.co.letsdelight.letsdelight.MainActivity@8eec139
The code writes Completed download of update file
to logcat but doesn't write URI successfully set
on an API 24 device. 该代码将
Completed download of update file
写入logcat,但没有写入URI successfully set
在API 24设备上URI successfully set
。 It works on API 23. Here is the important part of the code. 它适用于API23。这是代码的重要部分。 The
Update
class is invoked from MainActivity
with new Update(status, message).check(this);
使用
new Update(status, message).check(this);
从MainActivity
调用Update
类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);
}
}
}
The AndroidManifest.xml
file contains the following entry: 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
looks like this: file_provider_paths.xml
看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="cache" path="."/>
</paths>
I have tried changing context
to both getApplication()
and getApplicationContext()
which both result in a NullPointerException
but with slightly different resource wording. 我尝试将
context
都更改为getApplication()
和getApplicationContext()
,这两者都会导致NullPointerException
但资源措辞略有不同。
What else can I try to resolve this problem? 我还能尝试解决什么问题?
EDIT: 编辑:
I have modified the code to try and get to the bottom of the problem: 我已经修改了代码,以尝试探究问题的根源:
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
gets set to show the correct Provider Authority string. statusMessage
设置为显示正确的提供者授权字符串。 It does not get set to "uri set". 它不会设置为“ uri set”。 Therefore it is definitely the
FileProvider.getUriForFile()
that is failing. 因此,肯定是失败的
FileProvider.getUriForFile()
。
Given that context
is not null and the Authority is the correct string, what else could be throwing the error here? 鉴于
context
不为null,并且Authority是正确的字符串,还有什么可能在这里引发错误?
You are trying to call getString inside an non activity class try to replace 您正在尝试在非活动类中调用getString尝试替换
getString(R.string.file_provider_authority)
with 同
context.getString(R.string.file_provider_authority)
edit: I see you are extending activity in your Update
class did you declare it in the manifests? 编辑:我看到您正在扩展
Update
类中的活动,您是否在清单中声明了它? Why are you extending activity if you are already passing a context? 如果您已经传递了上下文,为什么还要扩展活动?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.