Firstly, I know this question asked many time and you can be sure that I read and tried all of them but i couldn't succeed sadly. I need to ask again to make clear for all newbie at android developing. BTW, i am learning from udacity. I am trying to open pdf files from assets. I found this (cw-omnibus ContentProvider) and this is very helpful but it is not dynamic and i couldn't figure out how to make this dynamic for all pdfs. Basicly, whenever i want to open a pdf via button, cardview so on, it should open using with fileprovider. Simply, i can copy and paste FileProvider with another name and i can use it. But if i have 20 pdfs, i will have lots of java file. This is like a walk istead of using bus to go to another city. I just wan to learn this how to do it. I do not know java much as well. I tried many things to take a bus but still i couldn't find a bus. I want some help. At github example, there is a "test.pdf" is a static as you see. When the intent is called "test.pdf" opened. I tired to assing variable for test.pdf and tried switch case for cardview (like button) but i couldn't call the variable from FileProvider.java and i tired bla bla bla lots of things. :(( I know i can do cardview with recyclerview but it is difficult for me right know to understand and customize so that i manually created cardviews. I am sharing all my codes below.
XML
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBg"
android:fillViewport="true"
tools:context="com.example.tk.buzebv2.Hizmetlerimiz">
<LinearLayout xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_kilavuzlar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_clicked1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/card_view_bottom"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:onClick="onClick"
card_view:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/hizmetlerimiz1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:text="Uzaktan Öğretim Sınıfı"
android:textColor="@color/colorDefaultText"
android:textSize="24sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:gravity="left"
android:lineSpacingMultiplier="1.3"
android:padding="@dimen/activity_horizontal_margin"
android:text="@string/hakkimizda_aciklama1"
android:textColor="@color/colorDefaultText"
android:textSize="16sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_clicked2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/card_view_bottom"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:onClick="onClick"
card_view:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/hizmetlerimiz2" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:text="Uzaktan Öğretim Hizmetleri"
android:textColor="@color/colorDefaultText"
android:textSize="24sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:gravity="left"
android:lineSpacingMultiplier="1.3"
android:padding="@dimen/activity_horizontal_margin"
android:text="@string/hakkimizda_aciklama3"
android:textColor="@color/colorDefaultText"
android:textSize="16sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_clicked3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/card_view_bottom"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:onClick="onClick"
card_view:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/hizmetlerimiz3" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:text="Online Sınav Hizmetleri"
android:textColor="@color/colorDefaultText"
android:textSize="24sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:gravity="left"
android:lineSpacingMultiplier="1.3"
android:padding="@dimen/activity_horizontal_margin"
android:text="@string/hakkimizda_aciklama3"
android:textColor="@color/colorDefaultText"
android:textSize="16sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
JAVA
package com.example.tk.buzebv2;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.util.Log;
import android.view.View;
public class Hizmetlerimiz extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hizmetlerimiz);
CardView b1= (CardView) findViewById(R.id.card_clicked1);
CardView b2= (CardView) findViewById(R.id.card_clicked2);
CardView b3= (CardView) findViewById(R.id.card_clicked3);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
}
public void onClick(View v) {
int i = v.getId();
if (i == R.id.card_toast) {
String hizmet_01 = "hizmet_01_a201.pdf";
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(FileProvider.CONTENT_URI
+ hizmet_01)));
} else if (i == R.id.card_toast1) {
String hizmet_02 = "hizmet_02_distance.pdf";
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(FileProvider.CONTENT_URI
+ hizmet_02)));
} else if (i == R.id.card_toast2) {
String hizmet_03 = "hizmet_03_online_sinav.pdf";
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(FileProvider.CONTENT_URI
+ hizmet_03)));
}
}
}
FileProvider.java
/***
Copyright (c) 2008-2014 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
From _The Busy Coder's Guide to Android Development_
https://commonsware.com/Android
*/
package com.commonsware.android.cp.files;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileProvider extends AbstractFileProvider {
public static final Uri CONTENT_URI=
Uri.parse("content://com.commonsware.android.cp.files/");
@Override
public boolean onCreate() {
File f=new File(getContext().getFilesDir(), "test.pdf");
if (!f.exists()) {
AssetManager assets=getContext().getResources().getAssets();
try {
copy(assets.open("test.pdf"), f);
}
catch (IOException e) {
Log.e("FileProvider", "Exception copying from assets", e);
return(false);
}
}
return(true);
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
File root=getContext().getFilesDir();
File f=new File(root, uri.getPath()).getAbsoluteFile();
if (!f.getPath().startsWith(root.getPath())) {
throw new
SecurityException("Resolved path jumped beyond root");
}
if (f.exists()) {
return(ParcelFileDescriptor.open(f, parseMode(mode)));
}
throw new FileNotFoundException(uri.getPath());
}
@Override
protected long getDataLength(Uri uri) {
File f=new File(getContext().getFilesDir(), uri.getPath());
return(f.length());
}
// following is from ParcelFileDescriptor source code
// Copyright (C) 2006 The Android Open Source Project
// (even though this method was added much after 2006...)
private static int parseMode(String mode) {
final int modeBits;
if ("r".equals(mode)) {
modeBits=ParcelFileDescriptor.MODE_READ_ONLY;
}
else if ("w".equals(mode) || "wt".equals(mode)) {
modeBits=
ParcelFileDescriptor.MODE_WRITE_ONLY
| ParcelFileDescriptor.MODE_CREATE
| ParcelFileDescriptor.MODE_TRUNCATE;
}
else if ("wa".equals(mode)) {
modeBits=
ParcelFileDescriptor.MODE_WRITE_ONLY
| ParcelFileDescriptor.MODE_CREATE
| ParcelFileDescriptor.MODE_APPEND;
}
else if ("rw".equals(mode)) {
modeBits=
ParcelFileDescriptor.MODE_READ_WRITE
| ParcelFileDescriptor.MODE_CREATE;
}
else if ("rwt".equals(mode)) {
modeBits=
ParcelFileDescriptor.MODE_READ_WRITE
| ParcelFileDescriptor.MODE_CREATE
| ParcelFileDescriptor.MODE_TRUNCATE;
}
else {
throw new IllegalArgumentException("Bad mode '" + mode + "'");
}
return modeBits;
}
}
The simplest thing to do would be to use my StreamProvider
, which handles all of this "out of the box" for you. It is based upon the FileProvider
offered by the Android support libraries, but it offers serving of files out of assets directly, without the intervening copy made by the particular sample app of mine that you looked at.
Otherwise, the sample that you have there will handle any number of PDFs. It happens to only set up one in onCreate()
. You could instead have onCreate()
fork a background thread and set up as many PDFs as you want. The rest of the code in the ContentProvider
would not require changing, as it just looks for files in getFilesDir()
based on the filename supplied on the Uri
.