2011-02-26 8 views
2

J'ai un dossier de pdf dans mon répertoire actif d'applications que je veux ouvrir en utilisant une application externe, ainsi a écrit mon fournisseur de contenu et je suis tryng pour le faire fonctionner mais ...Android - ouvrir le pdf dans l'application externe

voici le code:

contenu fournisseur:

package package.name; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.net.URI; 

import android.content.ContentProvider; 
import android.content.ContentValues; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.ParcelFileDescriptor; 

public class FileContentProvider extends ContentProvider { 
     private static final String URI_PREFIX = "content://package.name.filecontentprovider"; 

     public static String constructUri(String url) { 
      Uri uri = Uri.parse(url); 
      return uri.isAbsolute() ? url : URI_PREFIX + url; 
     } 

     @Override 
     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 
      URI uri1 = URI.create("file:///data/data/package.name/"+uri.getPath()); 
      File file = new File(uri1.getPath()); 
      ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); 
      return parcel; 
     } 

     @Override 
     public boolean onCreate() { 
      return true; 
     } 

     @Override 
     public int delete(Uri uri, String s, String[] as) { 
      throw new UnsupportedOperationException("Not supported by this provider"); 
     } 

     @Override 
     public String getType(Uri uri) { 
      throw new UnsupportedOperationException("Not supported by this provider"); 
     } 

     @Override 
     public Uri insert(Uri uri, ContentValues contentvalues) { 
      throw new UnsupportedOperationException("Not supported by this provider"); 
     } 

     @Override 
     public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) { 
      throw new UnsupportedOperationException("Not supported by this provider"); 
     } 

     @Override 
     public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { 
      throw new UnsupportedOperationException("Not supported by this provider"); 
     } 

    } 

et voici comment j'appelle l'ouverture du fichier:

File pdf = new File("assets/prova.pdf"); 
    Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("content://package.name/" + pdf)); 
    i.setType("application/pdf"); 
    startActivity(i); 

J'ai ajouté la ligne suivante dans le manifeste Android, dans la balise:

<provider android:name=".FileContentProvider" android:authorities="package.name" /> 

c'est la sortie logcat:

02-26 19:47:44.938: ERROR/AndroidRuntime(6494): Uncaught handler: thread main exiting due to uncaught exception 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tf.thinkdroid.samsung/com.tf.thinkdroid.pdf.app.PdfRenderScreen}: java.lang.NullPointerException 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.app.ActivityThread.access$2200(ActivityThread.java:119) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.os.Looper.loop(Looper.java:123) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.app.ActivityThread.main(ActivityThread.java:4363) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at java.lang.reflect.Method.invoke(Method.java:521) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at dalvik.system.NativeStart.main(Native Method) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494): Caused by: java.lang.NullPointerException 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at com.tf.thinkdroid.pdf.app.RenderScreen.onNewIntent(Unknown Source) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at com.tf.thinkdroid.pdf.app.RenderScreen.onCreate(Unknown Source) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at com.tf.thinkdroid.pdf.app.PdfRenderScreen.onCreate(Unknown Source) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459) 
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):  ... 11 more 

ne comprennent pas où le problème est, semble que les application externe ne peut pas obtenir le fichier.

merci pour toute aide!

Répondre

2

Je suis nouveau dans le développement android et j'ai passé toute la journée à chercher la raison pour laquelle mon fichier PDF stocké localement ne pouvait pas être ouvert par des applications externes. Je suis content d'avoir trouvé ce fil. En attendant, Marco a commencé à travailler et le décrit ici. Attention: italien anglais- service Google traduction pourrait aider ;-)

http://www.marcofaion.it/?p=7
http://web.archive.org/web/20111020204554/http://www.marcofaion.it/?p=7

Notes complémentaires à son howto pour les débutants:

La ligne Marco mentionne à insérer dans le Manifest .xml

<provider android:name=".FileContentProvider" android:authorities="package.name" /> 

doit être inséré wi mince l'étiquette <application ...></application>.

Et si vous envisagez d'avoir des noms de fichiers personnalisés, vous devez échanger

InputStream is = am.open("file.pdf"); 

avec

InputStream is = am.open(uri.getLastPathSegment()); 

fichiers PDF doivent être mis dans le dossier déjà existant actifs dans votre projet (surtout pas tout nouveau dossier res/assets ou sth.)! =)

2

setType() réinitialise votre Uri à null. Essayez de sauter le Uri dans le constructeur et en utilisant setDataAndType() à la place.

+0

J'ai essayé mais faire wsn't fonctionne pas, le logcat ne jette pas de xception mais le programme externe dit "chemin de fichier non valide" –

5

Ma mise en œuvre est ci-dessous. Notez que si votre nom de fichier est MyPdf.pdf, le fichier doit être assets/public_pdfs/MyPdf.pdf.mp3. Le chemin public_pdfs est d'exporter uniquement les fichiers PDF que vous voulez vraiment exporter, et l'extension .mp3 est d'empêcher la compression.

AndroidManifest.xml

<provider android:authorities="my.app.PdfContentProvider" android:enabled="true" android:exported="true" android:name="my.app.PdfContentProvider"> 
</provider> 

Ouverture d'un PDF

Intent intent = new Intent(); 
intent.setAction(Intent.ACTION_VIEW); 

Uri uri = Uri.parse("content://my.app.PdfContentProvider/" + filename); 
intent.setDataAndType(uri, "application/pdf"); 

startActivity(intent); 

PdfContentProvider.java

public class PdfContentProvider extends ContentProvider 
{ 
    private static final String PDFPATH = "public_pdfs/"; 

    @Override 
    public String getType(Uri uri) 
    { 
    return "application/pdf"; 
    } 

    @Override 
    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException 
    { 
    AssetManager am = getContext().getAssets(); 
    String file_name = uri.getLastPathSegment(); 

    if (file_name == null) throw new FileNotFoundException(); 
    AssetFileDescriptor afd = null; 
    try 
    { 
     afd = am.openFd(PDFPATH + file_name + ".mp3"); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    return afd; 
    } 

    private final static String[] COLUMNS = {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}; 

    @Override 
    /** 
    * This function is required for it to work on the Quickoffice at Android 4.4 (KitKat) 
    */ 
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 
    { 
    if (projection == null) 
    { 
     projection = COLUMNS; 
    } 

    String[] cols = new String[projection.length]; 
    Object[] values = new Object[projection.length]; 
    int i = 0; 
    for (String col : projection) 
    { 
     if (OpenableColumns.DISPLAY_NAME.equals(col)) 
     { 
     cols[i] = OpenableColumns.DISPLAY_NAME; 
     values[i++] = uri.getLastPathSegment(); 
     } 
     else if (OpenableColumns.SIZE.equals(col)) 
     { 
     cols[i] = OpenableColumns.SIZE; 
     values[i++] = AssetFileDescriptor.UNKNOWN_LENGTH; 
     } 
    } 

    cols = copyOf(cols, i); 
    values = copyOf(values, i); 

    final MatrixCursor cursor = new MatrixCursor(cols, 1); 
    cursor.addRow(values); 
    return cursor; 
    } 

    private static String[] copyOf(String[] original, int newLength) 
    { 
    final String[] result = new String[newLength]; 
    System.arraycopy(original, 0, result, 0, newLength); 
    return result; 
    } 

    private static Object[] copyOf(Object[] original, int newLength) 
    { 
    final Object[] result = new Object[newLength]; 
    System.arraycopy(original, 0, result, 0, newLength); 
    return result; 
    } 

    @Override 
    public boolean onCreate() 
    { 
    return true; 
    } 

    @Override 
    public Uri insert(Uri uri, ContentValues values) 
    { 
    return null; 
    } 

    @Override 
    public int delete(Uri uri, String selection, String[] selectionArgs) 
    { 
    return 0; 
    } 

    @Override 
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 
    { 
    return 0; 
    } 
} 
+0

Très très grand et travail intelligent pour découvrir la manière d'ouvrir le dossier de dossier actif. Cela devrait être une réponse correcte. +1 pour ça. – Smeet

+0

Semble un peu cassé. La seule chose qui arrive est Toast avec le message "Ce document ne peut pas être ouvert" ... – glace

Questions connexes