我有以下配置:来自一个应用程序的FileProvider
提供 drawables 类型的其他应用程序文件以及包含 json 结构的其他文本文件。 / p>
现在所有这些配置都有效,我从另一个应用程序收到内容uri (内容:// ...)这两种类型的文件。
我不知道的是如何在接收器应用程序中识别它收到的文件类型( drawable 或 json .txt )以及如何正确地将uri转换为这种文件类型之一。
这是接收器应用程序的当前活动:
public class MainActivity extends Activity {
ListView listView;
Cursor cursor;
Button bShowImageFiles, bShowJsonFiles;
Context mContext;
//TODO: Densities
static final String DENSITY_LOW = "ldpi";
static final String DENSITY_MEDIUM = "mdpi";
static final String DENSITY_HIGH = "hdpi";
static final String DENSITY_XHIGH = "xhdpi";
static final String DENSITY_XXHIGH = "xxhdpi";
public static final String FILES = "video";
public static final String PROVIDER_AUTHORITY = "some.authority";
public static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_AUTHORITY + "/");
public static Uri FILES_URI = Uri.parse("content://" + PROVIDER_AUTHORITY + "/" + FILES + "/");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
bShowImageFiles = (Button) findViewById(R.id.bShowImageFiles);
bShowJsonFiles = (Button) findViewById(R.id.bShowJsonFiles);
listView = (ListView) findViewById(R.id.listView1);
final String[] from = { "_id", "fileName" };
final int[] to = { R.id.textViewID, R.id.textFileName };
bShowImageFiles.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
configureFilesUri(getImageDirString(mContext));
cursor = getContentResolver().query(getImageFilesUri(mContext), null, null, null, null);
SimpleCursorAdapter sAdapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.row, cursor, from, to);
listView.setAdapter(sAdapter);
listView.setOnItemClickListener(new ListListener());
}
});
bShowJsonFiles.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
configureFilesUri(getJsonDirString());
cursor = getContentResolver().query(getJsonFilesUri(), null, null, null, null);
SimpleCursorAdapter sAdapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.row, cursor, from, to);
listView.setAdapter(sAdapter);
listView.setOnItemClickListener(new ListListener());
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class ListListener implements OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
cursor.moveToPosition(position);
String name = cursor.getString(cursor.getColumnIndex("fileName"));
Uri fileUri = Uri.parse(FILES_URI + name);
Log.i("DEBUG:", "path: " + fileUri);
String type = getMimeType(name);
try {
InputStream inputStream = getContentResolver().openInputStream(fileUri);
convertInputStreamToFile(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
public static String getMimeType(String uri) {
String extension = uri.substring(uri.lastIndexOf("."));
String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl(extension);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(mimeTypeMap);
return mimeType;
}
public static String getImageDirString(Context aContext) {
return "drawable-" + getDeviceDpiName(aContext);
}
public static String getJsonDirString() {
return "json";
}
public static Uri getImageFilesUri(Context aContext) {
return Uri.parse("content://" + PROVIDER_AUTHORITY + "/" + getImageDirString(aContext) + "/");
}
public static Uri getJsonFilesUri() {
return Uri.parse("content://" + PROVIDER_AUTHORITY + "/" + getJsonDirString() + "/");
}
public static String getDeviceDpiName(Context aContext) {
int density = aContext.getResources().getDisplayMetrics().densityDpi;
String dpi;
switch(density)
{
case DisplayMetrics.DENSITY_LOW:
dpi = DENSITY_LOW;
break;
case DisplayMetrics.DENSITY_MEDIUM:
dpi = DENSITY_MEDIUM;
break;
case DisplayMetrics.DENSITY_HIGH:
dpi = DENSITY_HIGH;
break;
case DisplayMetrics.DENSITY_XHIGH:
dpi = DENSITY_XHIGH;
break;
case DisplayMetrics.DENSITY_XXHIGH:
dpi = DENSITY_XXHIGH;
break;
default:
dpi = DENSITY_HIGH;
break;
}
return dpi;
}
private void configureFilesUri(String filesPath) {
FILES_URI = Uri.parse("content://" + PROVIDER_AUTHORITY + "/" + filesPath + "/");
}
private void convertInputStreamToFile( InputStream aInputStream) {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + "/kibo");
dir.mkdirs();
File file = new File(dir, "bubu.png");
try {
FileOutputStream os = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bytesRead;
//read from is to buffer
while((bytesRead = aInputStream.read(buffer)) !=-1){
os.write(buffer, 0, bytesRead);
}
aInputStream.close();
//flush OutputStream to write any buffered data to file
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.i("DEBUG", "******* File not found. Did you" +
" add a WRITE_EXTERNAL_STORAGE permission to the manifest?");
} catch (IOException e) {
e.printStackTrace();
}
}
说明:因此,您可以看到我现在将Uri
转移到InputStream
,其中使用{{1}将其转换为文件}。只要我从第二个项目获得drawables文件,这就可以工作。但是如果我得到一个json文件,应用程序崩溃了,因为我从这个文件得到的FileOutputStream
由于某种原因是空的。
更新(19.11.14):经过进一步的研究后,我意识到我无法为 .txt 文件获取InputStream的原因是因为它们在编译时被压缩(而不是可绘制的 .png 文件,这已经是压缩格式)
所以问题是:如何防止gradle压缩位于assets文件夹中的.txt文件?
答案 0 :(得分:3)
事实证明,这毕竟是压缩。添加以下内容:
aaptOptions {
noCompress 'txt', '.txt', 'json', '.json'
}
到 build.gradle 文件允许您在assets文件夹中禁用项目中特定文件类型的压缩。您可以通过以下链接获取更多信息:
答案 1 :(得分:0)
为了访问assets文件夹中的文件,您可以像这样获取InputStream:
InputStream is = getAssets().open("<filename>");
filename 可以是包含资源文件夹中路径的文件名。
因此,对于加载驻留在“assets / json-files / example.json”中的文件,你会这样做
InputStream is = getAssets().open("assets/json-files/example.json");