0

我有以下配置:FileProvider来自一个应用程序,该应用程序提供其他可绘制类型的应用程序文件和其他包含json结构的文本文件。

现在所有这些配置都工作了,我从一个应用程序的另一个应用程序接收到两种类型的文件的内容 uri (content://...)。

我不知道的是如何在接收器应用程序上识别它接收到的文件类型(drawablejson .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将. 只要我从第二个项目中获得可绘制文件,这就会起作用。但是,如果我得到一个 json 文件,应用程序就会崩溃,因为我从这个文件中得到的由于某种原因是空的。InputStreamFileOutputStreamInputStream

更新(19.11.14):经过额外的研究,我意识到我无法为.txt文件获取 InputStream 的原因是因为它们在编译时被压缩(而不是已经是可绘制的.png文件)压缩格式)

所以问题是:如何防止 gradle 压缩位于 assets 文件夹中的 .txt 文件?

4

2 回答 2

3

事实证明,这毕竟是压缩。添加以下内容:

aaptOptions {
    noCompress 'txt', '.txt', 'json', '.json'
}

build.gradle文件允许您在assets 文件夹中的项目中禁用特定文件类型的压缩。您可以在以下链接中获得更多信息:

aapt选项

于 2014-11-20T14:14:18.637 回答
0

为了访问资产文件夹中的文件,您可以像这样获取 InputStream:

InputStream is = getAssets().open("<filename>");

文件名可能是一个文件名,包括资产文件夹中的路径。

因此,要加载驻留在“assets/json-files/example.json”中的文件,您会这样做

InputStream is = getAssets().open("assets/json-files/example.json");
于 2014-11-19T11:25:57.370 回答