Assets sind Dateien auf dem Entwicklungscomputer. Sie sind nicht Dateien auf dem Gerät. Sie sind Einträge im ZIP-Archiv, das die APK ist.
In Java-Code (höchstwahrscheinlich), müssen Sie das Asset (von AssetManager
) in eine lokale Datei im Dateisystem kopieren, dann verwenden Sie Ihren systemeigenen Code diese lokale Dateisystemkopie.
Zum Beispiel dieser Aktivität, kopiert ein PDF aus einem Vermögenswert internen Speicher, in der Lage sein, es zu sehen FileProvider
verwenden und einen Drittanbieter-PDF-Viewer:
/***
Copyright (c) 2013 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.v4file;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v4.content.FileProvider;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class FilesCPDemo extends Activity {
private static final String AUTHORITY="com.commonsware.android.cp.v4file";
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
File f=new File(getFilesDir(), "test.pdf");
if (!f.exists()) {
AssetManager assets=getResources().getAssets();
try {
copy(assets.open("test.pdf"), f);
}
catch (IOException e) {
Log.e("FileProvider", "Exception copying from assets", e);
}
}
Intent i=
new Intent(Intent.ACTION_VIEW,
FileProvider.getUriForFile(this, AUTHORITY, f));
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(i);
finish();
}
static private void copy(InputStream in, File dst) throws IOException {
FileOutputStream out=new FileOutputStream(dst);
byte[] buf=new byte[1024];
int len;
while ((len=in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
In Ihrem Fall würden Sie tun, Dies funktioniert, bevor Sie Ihren JNI-Code starten, der die Schriftart benötigt. Und da der Pfad von Gerät zu Gerät oder von Benutzer zu Benutzer variieren kann, übergeben Sie den Pfad zur Schriftart an Ihren JNI-Code, anstatt zu versuchen, ihn in C/C++ hart zu codieren.
Also, ich habe die FileProvider-Daten im Manifest eingerichtet, aber ich habe einige Probleme, meine genauen Dateien zu finden. Ich habe 'neue Datei (Environment.getExternalStorageDirectory(). GetAbsolutePath(), "Arial.ttf"); 'verwendet, um zu versuchen, die Schriftart zu finden, aber das funktioniert nicht und es ist auch nicht, wenn ich' assets/'zum erstes Argument. Auch meine Pfade enthalten ' ' was könnte das Problem sein, ich weiß es nicht. Wo soll ich nach der Schriftdatei suchen? –
iHowell
@iHowell: "Ich habe die FileProvider-Daten im Manifest eingerichtet" - das ist mehr für meine Beispiel-App. Meistens habe ich darauf hingewiesen, wie ich sehe, ob ich die Datei bereits in 'onCreate()' habe, und wenn nicht, kopiere ich sie() aus Assets. Sie brauchen 'FileProvider' nicht, aber meine Beispiel-App hat es getan. "Wo soll ich nach der Schriftdatei suchen?" - wo immer du es kopierst. In meinem Fall handelt es sich um eine Datei in 'getFilesDir()', wie Sie in der 'onCreate()' Methode sehen können. – CommonsWare
Wenn ich sage, wo soll ich danach suchen, meine ich, dass ich das Original nicht finden kann. Der eine in meinem Assets-Ordner. Ich bekomme eine 'java.io.FileNotFoundException: /storage/emulate/0/Arial.ttf: Öffnen fehlgeschlagen: EACCES (Berechtigung verweigert)' Fehler. – iHowell