Android 无法在浏览器中打开本地文件

Android 无法在浏览器中打开本地文件,android,html,android-intent,browser,Android,Html,Android Intent,Browser,(我已与SO中的其他类似问题核对) 我正在尝试创建一个HTML编辑器。我有一个编辑文本,想在浏览器中打开输入的HTML代码。我将编辑文本内容复制到一个.html文件中,然后打开它 String filename = "temp.html"; File file = new File(getActivity().getFilesDir(), filename); FileOutputStream outputStream; try { outputStream = getActiv

(我已与SO中的其他类似问题核对)

我正在尝试创建一个HTML编辑器。我有一个编辑文本,想在浏览器中打开输入的HTML代码。我将编辑文本内容复制到一个.html文件中,然后打开它

String filename = "temp.html";
File file = new File(getActivity().getFilesDir(), filename);
FileOutputStream outputStream;
    try {
    outputStream = getActivity().openFileOutput(filename,
            Context.MODE_PRIVATE);
    outputStream.write(editText.getText().toString().getBytes());
    outputStream.close();
} catch (Exception e) {
    e.printStackTrace();
}

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));
startActivity(intent);
我在清单中添加了
。但在我单击open之后,使用我获得的应用程序选项的完整操作是Adobe Reader和UTorrent remote。浏览器没有显示。我的手机里有Opera和股票浏览器。我的代码有什么问题?我用了一种定制的字体

注:

  • 我不想在我的应用程序中使用WebView。我只想在浏览器中打开它
  • “getActivity()”因为此代码位于片段中
编辑:

File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/temp");
        dir.mkdirs();
        File file = new File(dir, "temp.html");
        FileOutputStream outputStream;
        try {
            outputStream = new FileOutputStream(file);
            outputStream.write(et.getText().toString().getBytes());
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();
        }

        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));
        startActivity(intent);
更改了将文件写入外部目录的代码。问题依然存在

我的代码有什么问题

首先,第三方应用程序无法访问您的文件,因为它是内部存储上的私有文件

其次,浏览器应用不需要支持
file://
Uri
值,甚至不需要支持
content://
Uri
值(如果您想使用它向第三方应用公开私有文件)

如果要显示本地HTML,请使用
WebView
小部件。或者,反复浏览可用Web浏览器应用程序的列表,直到找到一个支持
文件://
内容://
Uri
方案的应用程序,然后鼓励用户安装该浏览器

我的代码有什么问题

首先,第三方应用程序无法访问您的文件,因为它是内部存储上的私有文件

其次,浏览器应用不需要支持
file://
Uri
值,甚至不需要支持
content://
Uri
值(如果您想使用它向第三方应用公开私有文件)


如果要显示本地HTML,请使用
WebView
小部件。或者,反复浏览可用的Web浏览器应用程序列表,直到找到一个支持
文件://
内容://
Uri
方案的应用程序,然后鼓励用户安装该浏览器。

Android内置的浏览器应用程序可以访问内部存储器的私有数据区域中的文件,但这需要一些工作才能完成(我花了整整两周的时间才弄明白)。首先,让我们处理
AndroidManifest.xml
文件。在文件顶部附近(就在
块之前),您需要指定此“权限”:

安装程序的activity类的第一部分需要如下内容:

<activity
  android:name="com.android.browser"
  android:parentActivityName="com.myHTMLeditor.Installer"
  android:allowTaskReparenting="true"
  android:autoRemoveFromRecents="true"
  android:launchMode="standard"
  android:documentLaunchMode="intoExisting"
  android:excludeFromRecents="true"
  android:exported="false"
  android:noHistory="true"
  android:screenOrientation="portrait"
  android:stateNotNeeded="true"
  >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.APP_BROWSER" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.OPENABLE" />
    <data
      android.scheme="file"
      android.host="com.myHTMLeditor"
      android.path="/data/data/com.myHTMLeditor/files/MainPage.html"
    />
  </intent-filter>
</activity>
public class Installer extends Activity
{ boolean btmp, passfail=false;   //declare various variables global to the class
  File apphome, fmd;
  InputStream inp;
  FileOutputStream fout;
  Intent Browse;
  Uri u;
  Uri.Builder b;
  String fn;
  int lng;
  byte[] buffer=new byte[1024];
public void doInstall()
{ apphome=getFilesDir(); //VERIFY WITH DEBUGGER (for Manifest file): /data/data/com.myHTMLeditor/files
  apphome.setReadable(true, false);  //THIS IS KEY to letting the browser access files
  apphome.setWritable(true, false);  // in your application's private directory
  fn=apphome.getPath()+"/MainPage.html"; //create file name
  fmd=new File(fn);                      //create file object
  btmp=fmd.createNewFile();              //create actual file
  if(btmp)
  { fout=new FileOutputStream(fmd);
    while( /*you have data to put into the file, fetch some of it into the byte-buffer */ )
      fout.write(buffer, 0, lng);  //lng is number of bytes put into the buffer
    fout.close();
  }
  if(btmp) //if successfully created the file, need to make it readable by the browser, too!
  { fmd.setReadable(true, false);
    fmd.setWritable(true, true);
  }

  passfail=true; //only do this when satisfied that all files are installed properly!
实际执行安装的类函数或方法需要以下代码:

<activity
  android:name="com.android.browser"
  android:parentActivityName="com.myHTMLeditor.Installer"
  android:allowTaskReparenting="true"
  android:autoRemoveFromRecents="true"
  android:launchMode="standard"
  android:documentLaunchMode="intoExisting"
  android:excludeFromRecents="true"
  android:exported="false"
  android:noHistory="true"
  android:screenOrientation="portrait"
  android:stateNotNeeded="true"
  >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.APP_BROWSER" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.OPENABLE" />
    <data
      android.scheme="file"
      android.host="com.myHTMLeditor"
      android.path="/data/data/com.myHTMLeditor/files/MainPage.html"
    />
  </intent-filter>
</activity>
public class Installer extends Activity
{ boolean btmp, passfail=false;   //declare various variables global to the class
  File apphome, fmd;
  InputStream inp;
  FileOutputStream fout;
  Intent Browse;
  Uri u;
  Uri.Builder b;
  String fn;
  int lng;
  byte[] buffer=new byte[1024];
public void doInstall()
{ apphome=getFilesDir(); //VERIFY WITH DEBUGGER (for Manifest file): /data/data/com.myHTMLeditor/files
  apphome.setReadable(true, false);  //THIS IS KEY to letting the browser access files
  apphome.setWritable(true, false);  // in your application's private directory
  fn=apphome.getPath()+"/MainPage.html"; //create file name
  fmd=new File(fn);                      //create file object
  btmp=fmd.createNewFile();              //create actual file
  if(btmp)
  { fout=new FileOutputStream(fmd);
    while( /*you have data to put into the file, fetch some of it into the byte-buffer */ )
      fout.write(buffer, 0, lng);  //lng is number of bytes put into the buffer
    fout.close();
  }
  if(btmp) //if successfully created the file, need to make it readable by the browser, too!
  { fmd.setReadable(true, false);
    fmd.setWritable(true, true);
  }

  passfail=true; //only do this when satisfied that all files are installed properly!
如果安装过程在该目录中创建了一个文件,则需要如下内容:

<activity
  android:name="com.android.browser"
  android:parentActivityName="com.myHTMLeditor.Installer"
  android:allowTaskReparenting="true"
  android:autoRemoveFromRecents="true"
  android:launchMode="standard"
  android:documentLaunchMode="intoExisting"
  android:excludeFromRecents="true"
  android:exported="false"
  android:noHistory="true"
  android:screenOrientation="portrait"
  android:stateNotNeeded="true"
  >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.APP_BROWSER" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.OPENABLE" />
    <data
      android.scheme="file"
      android.host="com.myHTMLeditor"
      android.path="/data/data/com.myHTMLeditor/files/MainPage.html"
    />
  </intent-filter>
</activity>
public class Installer extends Activity
{ boolean btmp, passfail=false;   //declare various variables global to the class
  File apphome, fmd;
  InputStream inp;
  FileOutputStream fout;
  Intent Browse;
  Uri u;
  Uri.Builder b;
  String fn;
  int lng;
  byte[] buffer=new byte[1024];
public void doInstall()
{ apphome=getFilesDir(); //VERIFY WITH DEBUGGER (for Manifest file): /data/data/com.myHTMLeditor/files
  apphome.setReadable(true, false);  //THIS IS KEY to letting the browser access files
  apphome.setWritable(true, false);  // in your application's private directory
  fn=apphome.getPath()+"/MainPage.html"; //create file name
  fmd=new File(fn);                      //create file object
  btmp=fmd.createNewFile();              //create actual file
  if(btmp)
  { fout=new FileOutputStream(fmd);
    while( /*you have data to put into the file, fetch some of it into the byte-buffer */ )
      fout.write(buffer, 0, lng);  //lng is number of bytes put into the buffer
    fout.close();
  }
  if(btmp) //if successfully created the file, need to make it readable by the browser, too!
  { fmd.setReadable(true, false);
    fmd.setWritable(true, true);
  }

  passfail=true; //only do this when satisfied that all files are installed properly!
现在,对于启动浏览器以加载
MainPage.html
文件的函数/方法:

public void runBrowser(View vw)
{ if(passfail)
  { Browse = new Intent(Intent.ACTION_VIEW, Uri.parse("file://"+apphome.getPath()+"/MainPage.html"));
    Browse=Browse.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));
    Browse=Browse.addCategory(Intent.CATEGORY_LAUNCHER);
    Browse=Browse.addCategory(Intent.CATEGORY_APP_BROWSER);
    Browse=Browse.addCategory(Intent.CATEGORY_DEFAULT);
    Browse=Browse.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    Browse=Browse.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Browse=Browse.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    b=new Uri.Builder();
    b=b.encodedAuthority(apphome.getPath());
    b=b.scheme("file");
    b=b.path("/MainPage.html");
    u=b.build();
    u.getHost(); //this works to set the internal "host" property from the "authority" property
    Browse=Browse.setDataAndNormalize(u);
    startActivity(Browse);
} }

最后一点注意:我在这项工作中使用了Android API 21。我并没有看到早期的API版本能够做到这一点有多远。

Android的内置浏览器应用程序可以访问内部存储的私有数据区中的文件,但需要一些工作才能完成(我花了整整两周的时间才弄清楚)。首先,让我们处理
AndroidManifest.xml
文件。在文件顶部附近(就在
块之前),您需要指定此“权限”:

安装程序的activity类的第一部分需要如下内容:

<activity
  android:name="com.android.browser"
  android:parentActivityName="com.myHTMLeditor.Installer"
  android:allowTaskReparenting="true"
  android:autoRemoveFromRecents="true"
  android:launchMode="standard"
  android:documentLaunchMode="intoExisting"
  android:excludeFromRecents="true"
  android:exported="false"
  android:noHistory="true"
  android:screenOrientation="portrait"
  android:stateNotNeeded="true"
  >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.APP_BROWSER" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.OPENABLE" />
    <data
      android.scheme="file"
      android.host="com.myHTMLeditor"
      android.path="/data/data/com.myHTMLeditor/files/MainPage.html"
    />
  </intent-filter>
</activity>
public class Installer extends Activity
{ boolean btmp, passfail=false;   //declare various variables global to the class
  File apphome, fmd;
  InputStream inp;
  FileOutputStream fout;
  Intent Browse;
  Uri u;
  Uri.Builder b;
  String fn;
  int lng;
  byte[] buffer=new byte[1024];
public void doInstall()
{ apphome=getFilesDir(); //VERIFY WITH DEBUGGER (for Manifest file): /data/data/com.myHTMLeditor/files
  apphome.setReadable(true, false);  //THIS IS KEY to letting the browser access files
  apphome.setWritable(true, false);  // in your application's private directory
  fn=apphome.getPath()+"/MainPage.html"; //create file name
  fmd=new File(fn);                      //create file object
  btmp=fmd.createNewFile();              //create actual file
  if(btmp)
  { fout=new FileOutputStream(fmd);
    while( /*you have data to put into the file, fetch some of it into the byte-buffer */ )
      fout.write(buffer, 0, lng);  //lng is number of bytes put into the buffer
    fout.close();
  }
  if(btmp) //if successfully created the file, need to make it readable by the browser, too!
  { fmd.setReadable(true, false);
    fmd.setWritable(true, true);
  }

  passfail=true; //only do this when satisfied that all files are installed properly!
实际执行安装的类函数或方法需要以下代码:

<activity
  android:name="com.android.browser"
  android:parentActivityName="com.myHTMLeditor.Installer"
  android:allowTaskReparenting="true"
  android:autoRemoveFromRecents="true"
  android:launchMode="standard"
  android:documentLaunchMode="intoExisting"
  android:excludeFromRecents="true"
  android:exported="false"
  android:noHistory="true"
  android:screenOrientation="portrait"
  android:stateNotNeeded="true"
  >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.APP_BROWSER" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.OPENABLE" />
    <data
      android.scheme="file"
      android.host="com.myHTMLeditor"
      android.path="/data/data/com.myHTMLeditor/files/MainPage.html"
    />
  </intent-filter>
</activity>
public class Installer extends Activity
{ boolean btmp, passfail=false;   //declare various variables global to the class
  File apphome, fmd;
  InputStream inp;
  FileOutputStream fout;
  Intent Browse;
  Uri u;
  Uri.Builder b;
  String fn;
  int lng;
  byte[] buffer=new byte[1024];
public void doInstall()
{ apphome=getFilesDir(); //VERIFY WITH DEBUGGER (for Manifest file): /data/data/com.myHTMLeditor/files
  apphome.setReadable(true, false);  //THIS IS KEY to letting the browser access files
  apphome.setWritable(true, false);  // in your application's private directory
  fn=apphome.getPath()+"/MainPage.html"; //create file name
  fmd=new File(fn);                      //create file object
  btmp=fmd.createNewFile();              //create actual file
  if(btmp)
  { fout=new FileOutputStream(fmd);
    while( /*you have data to put into the file, fetch some of it into the byte-buffer */ )
      fout.write(buffer, 0, lng);  //lng is number of bytes put into the buffer
    fout.close();
  }
  if(btmp) //if successfully created the file, need to make it readable by the browser, too!
  { fmd.setReadable(true, false);
    fmd.setWritable(true, true);
  }

  passfail=true; //only do this when satisfied that all files are installed properly!
如果安装过程在该目录中创建了一个文件,则需要如下内容:

<activity
  android:name="com.android.browser"
  android:parentActivityName="com.myHTMLeditor.Installer"
  android:allowTaskReparenting="true"
  android:autoRemoveFromRecents="true"
  android:launchMode="standard"
  android:documentLaunchMode="intoExisting"
  android:excludeFromRecents="true"
  android:exported="false"
  android:noHistory="true"
  android:screenOrientation="portrait"
  android:stateNotNeeded="true"
  >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.APP_BROWSER" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.OPENABLE" />
    <data
      android.scheme="file"
      android.host="com.myHTMLeditor"
      android.path="/data/data/com.myHTMLeditor/files/MainPage.html"
    />
  </intent-filter>
</activity>
public class Installer extends Activity
{ boolean btmp, passfail=false;   //declare various variables global to the class
  File apphome, fmd;
  InputStream inp;
  FileOutputStream fout;
  Intent Browse;
  Uri u;
  Uri.Builder b;
  String fn;
  int lng;
  byte[] buffer=new byte[1024];
public void doInstall()
{ apphome=getFilesDir(); //VERIFY WITH DEBUGGER (for Manifest file): /data/data/com.myHTMLeditor/files
  apphome.setReadable(true, false);  //THIS IS KEY to letting the browser access files
  apphome.setWritable(true, false);  // in your application's private directory
  fn=apphome.getPath()+"/MainPage.html"; //create file name
  fmd=new File(fn);                      //create file object
  btmp=fmd.createNewFile();              //create actual file
  if(btmp)
  { fout=new FileOutputStream(fmd);
    while( /*you have data to put into the file, fetch some of it into the byte-buffer */ )
      fout.write(buffer, 0, lng);  //lng is number of bytes put into the buffer
    fout.close();
  }
  if(btmp) //if successfully created the file, need to make it readable by the browser, too!
  { fmd.setReadable(true, false);
    fmd.setWritable(true, true);
  }

  passfail=true; //only do this when satisfied that all files are installed properly!
现在,对于启动浏览器以加载
MainPage.html
文件的函数/方法:

public void runBrowser(View vw)
{ if(passfail)
  { Browse = new Intent(Intent.ACTION_VIEW, Uri.parse("file://"+apphome.getPath()+"/MainPage.html"));
    Browse=Browse.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));
    Browse=Browse.addCategory(Intent.CATEGORY_LAUNCHER);
    Browse=Browse.addCategory(Intent.CATEGORY_APP_BROWSER);
    Browse=Browse.addCategory(Intent.CATEGORY_DEFAULT);
    Browse=Browse.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    Browse=Browse.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Browse=Browse.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    b=new Uri.Builder();
    b=b.encodedAuthority(apphome.getPath());
    b=b.scheme("file");
    b=b.path("/MainPage.html");
    u=b.build();
    u.getHost(); //this works to set the internal "host" property from the "authority" property
    Browse=Browse.setDataAndNormalize(u);
    startActivity(Browse);
} }

最后一点注意:我在这项工作中使用了Android API 21。我没有考虑过早期的API版本有多远才能做到这一点。

所以我的解决方案是我必须创建一个第三方bowser可以访问的文件?@ArjunU:将它放在外部存储上。或者,通过
content://
Uri
从内部存储器提供文件。而且,无论哪种情况,您仍然需要找到一个兼容的浏览器。请注意,在撰写本文时,Chrome不兼容,尽管Firefox可能是用于外部存储上的文件。同样的问题@阿诸奴:你需要安装一个支持
文件://
方案的浏览器。铬不会。AOSP浏览器应用程序不支持。Firefox可能会。@ArjunU:Hmmm。。。您可以尝试使用
setDataAndType()
来指定您的内容是
text/html
。因此,我的解决方案是我必须创建一个第三方bowser可以访问的文件?@ArjunU:将其放在外部存储上。或者,通过
content://
Uri
从内部存储器提供文件。而且,无论哪种情况,您仍然需要找到一个兼容的浏览器。请注意,在撰写本文时,Chrome不兼容,尽管Firefox可能是用于外部存储上的文件。同样的问题@阿诸奴:你需要安装一个支持
文件://
方案的浏览器。铬不会。AOSP浏览器应用程序不支持。Firefox可能会。@ArjunU:Hmmm。。。您可以尝试使用
setDataAndType()
指定您的内容为
text/html