AndroidManifest.xml中如何定义自定义文件类型?

请教大家,
我有自己定义的一种扩展名的文件,macf文件,其实是sqlite的db数据库文件。
我想安装了app之后,在“用其他应用打开”可以看到我的app。
AndroidManifest.xml 中我已经做了如下的定义:

            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="file" />
            <data android:scheme="content" />
            <data android:mimeType="*/*" />
            <data android:host="*" />
            <data android:pathPattern=".*\\\\.macf" />
            <data android:pathPattern=".*\\\\..*\\\\.macf" />
            <data android:pathPattern=".*\\\\..*\\\\..*\\\\.macf" />
            <data android:pathPattern=".*\\\\..*\\\\..*\\\\..*\\\\.macf" />

但是始终不起作用,不知道问题是出在哪里?

您已经在 AndroidManifest.xml 文件中做了很多正确的定义,应该可以让您的应用程序成为可以打开 .macf 扩展名文件的一种应用程序。

但根据您所述的详细信息,似乎您忽略了一件重要的事情,即使您的应用程序被成功地注册为可以处理 .macf 文件的应用程序,该文件也必须由用户安装并与您的应用程序关联。如果用户在设备上没有您的应用程序安装,他们将无法打开 .macf 文件。

因此,我建议您采取以下步骤:

  1. 确认您已经正确注册您的应用程序。您已经在AndroidManifest.xml文件中定义了大量与“data”相关的标记,如果这些标记正确处理 .macf 文件,则您的应用程序应该已成功注册。

  2. 确认您的应用程序与 .macf 文件关联。您需要将 .macf 文件与您的应用程序关联,以便 Android 知道何时应该使用您的应用程序来打开该文件。可以通过两种方式实现:

    • 通过应用的界面来实现。您可以为您的应用程序开发一个简单的文件浏览器,允许用户通过选择“打开文件”并选择 .macf 文件来将文件与您的应用程序关联。

    • 通过设置操作系统默认关联来实现。如果用户在设备上具有 .macf 文件(例如通过电子邮件或从 web 下载),他们可以选择用您的应用程序打开文件。这是通过 Android 的“应用程序选择器”来实现的,允许用户选择哪个应用程序打开该文件。

希望这些步骤能够帮助您成功地将您的应用程序与 .macf 文件关联起来。

该回答引用ChatGPT

在AndroidManifest.xml中定义自定义文件类型,主要有两步:

  1. 定义mimeType。在标签中添加android:mimeType属性,如:
    xml
<data android:mimeType="application/macf" />

这定义了macf文件的mimeType为application/macf。
2. 添加intent-filter。在activity或service中添加一个intent-filter,包含以下内容:

  • ,声明可以 view 此文件的activity
  • ,指明可以打开的mimeType
    如:
    xml
<activity>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="application/macf" />
    </intent-filter>
</activity> 
所以,完整的AndroidManifest.xml可以这样定义:
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">

    <data android:mimeType="application/macf" />
    
    <application>
        <activity>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="application/macf" />
            </intent-filter>
        </activity>
    </application>
</manifest>

这样,macf文件就注册到了系统,安装app后可以在其他应用的“打开方式”中看到你的app并打开macf文件。
注意:

  1. 和 是无效的,需要定义具体的mimeType。
  2. 如果macf文件可以由其他应用打开,还需要在这些应用的AndroidManifest.xml中 similarly地定义mimeType和intent-filter。
不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/243540
  • 这篇博客也不错, 你可以看下Android 拷贝db文件到sqlite数据库。
  • 除此之外, 这篇博客: Android 入个门中的 7、编写一APP,实现SQLite数据库的增删改查。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    设计一个课程管理APP,实现SQLite数据库的增删改查

    在工程中创建MainActivity.java、InsertActivity.java、QueryActivity.java、UpdateActivity.java、DeleteActivity.java以及相应的布局文件activity_main.xml、activity_insert.xml、activity_query.xml、activity_update.xml、activity_delete.xml,以及数据库适配器DBAdapter.java、实体类Course.java。

    数据库工具类DBAdapter.java,其中定义了内部类BookDBHelper,它是SQLiteOpenHelper的子类,用于建立、更新和打开数据库。主要代码:

    public class DBAdapter {
        public static final String ID = "_id";
        public static final String COURSENAME = "courseName";
        public static final String TEACHER = "teacher";
        public static final String TIME = "time";
        private static final String DB_NAME = "course.db";
        private static final String DB_TABLE = "courseinfo";
        private static final int DB_VERSION = 1;
        private final Context context;
        private SQLiteDatabase db;
        private CourseDBHelper dbHelper;
        public DBAdapter(Context context) {
            this.context = context;
        }
        public void close() {   // Close the database
            if (db != null) {
                db.close();
                db = null;
            }
        }
        public void open() throws SQLiteException { // Open the database
            dbHelper = new CourseDBHelper(context, DB_NAME, null, DB_VERSION);
            try {
                db = dbHelper.getWritableDatabase();
            } catch (SQLiteException ex) {
                db = dbHelper.getReadableDatabase();
            }
        }
        public long insert(Course course) {
            ContentValues courseValues = new ContentValues();
            courseValues.put(COURSENAME, course.getCourseName());
            courseValues.put(TEACHER, course.getTeacher());
            courseValues.put(TIME, course.getTime());
            return db.insert(DB_TABLE, null, courseValues);
        }
        public Course[] queryAll() {
            Cursor results =  db.query(DB_TABLE, 
                   new String[] { ID, COURSENAME, TEACHER, TIME},
                   null, null, null, null, null);
            return ConvertToCourse(results);
        }
        public Course[] queryOne(long id) {
            Cursor results =  db.query(DB_TABLE, new String[] { ID, COURSENAME, TEACHER, TIME},
                    ID + "=" + id, null, null, null, null);
            return ConvertToCourse(results);
        }
        private Course[] ConvertToCourse(Cursor cursor){
            int resultCounts = cursor.getCount();
            if (resultCounts == 0 || !cursor.moveToFirst()){
                return null;
            }
            Course[] courseList = new Course[resultCounts];
            for (int i = 0 ; i<resultCounts; i++){
                courseList[i] = new Course();
                int newId = cursor.getInt(0);
                courseList[i].setID(newId);
                String newCourseName = cursor.getString(cursor.getColumnIndex(COURSENAME));
                courseList[i].setCourseName(newCourseName);
                String newTeacher = cursor.getString(cursor.getColumnIndex(TEACHER));
                courseList[i].setTeacher(newTeacher);
                float newTime = cursor.getFloat(cursor.getColumnIndex(TIME));
                courseList[i].setTime(newTime);
                cursor.moveToNext();
            }
            return courseList;
        }
        public long deleteAll() {
            return db.delete(DB_TABLE, null, null);
        }
        public long deleteOne(long id) {
            return db.delete(DB_TABLE,  ID + "=" + id, null);
        }
        public long updateOne(long id , Course course){
            ContentValues courseValues = new ContentValues();
            courseValues.put(COURSENAME, course.getCourseName());
            courseValues.put(TEACHER, course.getTeacher());
            courseValues.put(TIME, course.getTime());
            return db.update(DB_TABLE, courseValues,  ID + "=" + id, null);
        }
    
        // 静态Helper类,用于建立、更新和打开数据库
        private static class CourseDBHelper extends SQLiteOpenHelper {
            private static final String DB_CREATE = "create table " +
                    DB_TABLE + " (" + ID + " integer primary key autoincrement, " +
                    COURSENAME + " text not null, " + TEACHER + " text," + TIME + " float);";
            public CourseDBHelper(Context context, String name, CursorFactory factory, int version) {
                super(context, name, factory, version);
            }
            @Override
            public void onCreate(SQLiteDatabase _db) {
                _db.execSQL(DB_CREATE);
            }
            @Override
            public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion) {
                _db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
                onCreate(_db);
            }
        }
    }
    

    其余详细代码文件可详见附件SQLiteDemo工程文件夹。

    运行结果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3QizxtdX-1595863946493)(https://i.loli.net/2020/07/16/C5ghqGTxWRmrUH4.png)]

  • 您还可以看一下 张晨光老师的零基础学安卓Android移动开发课程中的 使用工具打开SqlIte数据库小节, 巩固相关知识点

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

好的 谢谢大家