编译成APK还是jar..
jar的话,用ant就好了。抄一段。很快的。。
APK我不知道

解决方案 »

  1.   

    . build/envsetup.sh
    用编辑器看看envsetup.sh
    写个Android.mk文件。就可以用mm命令编译了
      

  2.   

    没看懂  能细说下么  呵呵  android.mk的文件时什么啊  没听过啊
      

  3.   

    在Linux下android源码编译都是通过android.mk来实现的。
    你可以看一下android/packages/apps/下的应用,根目录下都有这个文件,照着搬一个过来就可以用。
      

  4.   

    SDK doc里面不是有么?Creating an Android ProjectTo create an Android project, you must use the android tool. When you create a new project with android, it will generate a project directory with some default application files, stub files, configuration files and a build file.Creating a new Project
    If you're starting a new project, use the android create project command to generate all the necessary files and folders.To create a new Android project, open a command-line, navigate to the tools/ directory of your SDK and run:android create project \
    --target <targetID> \
    --path /path/to/your/project \
    --activity <your_activity_name> \
    --package <your_package_namespace>
    target is the "build target" for your application. It corresponds to an Android platform library (including any add-ons, such as Google APIs) that you would like to build your project against. To see a list of available targets and their corresponding IDs, execute: android list targets.
    path is the location of your project directory. If the directory does not exist, it will be created for you.
    activity is the name for your Activity class. This class file will be created for you inside <path_to_your_project>/src/<your_package_namespace_path>/.
    package is the package namespace for your project, following the same rules as for packages in the Java programming language.
    Here's an example:android create project \
    --target 1 \
    --path ./myProject \
    --activity MyActivity \
    --package com.example.myproject
    The tool generates the following files and directories:AndroidManifest.xml - The application manifest file, synced to the specified Activity class for the project.
    build.xml - Build file for Ant.
    default.properties - Properties for the build system. Do not modify this file.
    build.properties - Customizable properties for the build system. You can edit this file to overried default build settings used by Ant.
    src/your/package/namespace/ActivityName.java - The Activity class you specified during project creation.
    bin/ - Output directory for the build script.
    gen/ - Holds Ant-generated files, such as R.java.
    libs/ - Holds private libraries.
    res/ - Holds project resources.
    src/ - Holds source code.
    tests/ - Holds a duplicate of all-of-the-above, for testing purposes.
    Once you've created your project, you're ready to begin development. You can move your project folder wherever you want for development, but keep in mind that you must use the Android Debug Bridge (adb) — located in the SDK tools/ directory — to send your application to the emulator (discussed later). So you need access between your project solution and the tools/ folder.Note: You should refrain from moving the location of the SDK directory, because this will break the build scripts. (They will need to be manually updated to reflect the new SDK location before they will work again.)Updating a project
    If you're upgrading a project from an older version of the Android SDK or want to create a new project from existing code, use the android update project command to update the project to the new development environment. You can also use this command to revise the build target of an existing project (with the --target option). The android tool will generate any files and folders (listed in the previous section) that are either missing or need to be updated, as needed for the Android project.To update an existing Android project, open a command-line and navigate to the tools/ directory of your SDK. Now run:android update project --target <targetID> --path path/to/your/project/
    target is the "build target" for your application. It corresponds to an Android platform library (including any add-ons, such as Google APIs) that you would like to build your project against. To see a list of available targets and their corresponding IDs, execute: android list targets.
    path is the location of your project directory.
    Here's an example:android update project --target 2 --path ./myProject
    Preparing to Sign Your ApplicationAs you begin developing Android applications, understand that all Android applications must be digitally signed before the system will install them on an emulator or device. There are two ways to do this: with a debug key (for immediate testing on an emulator or development device) or with a private key (for application distribution).The Android build tools help you get started by automatically signing your .apk files with a debug key at build time. This means that you can compile your application and install it on the emulator without having to generate your own private key. However, please note that if you intend to publish your application, you must sign the application with your own private key, rather than the debug key generated by the SDK tools.Please read Signing Your Applications, which provides a thorough guide to application signing on Android and what it means to you as an Android application developer.Building Your ApplicationThere are two ways to build your application: one for testing/debugging your application — debug mode — and one for building your final package for release — release mode. As described in the previous section, your application must be signed before it can be installed on an emulator or device.Whether you're building in debug mode or release mode, you need to use the Ant tool to compile and build your project. This will create the .apk file that is installed onto the emulator or device. When you build in debug mode, the .apk file is automatically signed by the SDK tools with a debug key, so it's instantly ready for installation (but only onto an emulator or attached development device). When you build in release mode, the .apk file is unsigned, so you must manually sign it with your own private key, using Keytool and Jarsigner.It's important that you read and understand Signing Your Applications, particularly once you're ready to release your application and share it with end-users. That document describes the procedure for generating a private key and then using it to sign your .apk file. If you're just getting started, however, you can quickly run your applications on an emulator or your own development device by building in debug mode.If you don't have Ant, you can obtain it from the Apache Ant home page. Install it and make sure it is in your executable PATH. Before calling Ant, you need to declare the JAVA_HOME environment variable to specify the path to where the JDK is installed.Note: When installing JDK on Windows, the default is to install in the "Program Files" directory. This location will cause ant to fail, because of the space. To fix the problem, you can specify the JAVA_HOME variable like this: set JAVA_HOME=c:\Prora~1\Java\. The easiest solution, however, is to install JDK in a non-space directory, for example: c:\java\jdk1.6.0_02.Building in debug mode
    For immediate application testing and debugging, you can build your application in debug mode and immediately install it on an emulator. In debug mode, the build tools automatically sign your application with a debug key. However, you can (and should) also test your application in release mode. Debug mode simply allows you to run your application without manually signing the application.To build in debug mode:Open a command-line and navigate to the root of your project directory.
    Use Ant to compile your project in debug mode:
    ant debug
    This creates your Android application .apk file inside the project bin/ directory, named <your_DefaultActivity_name>-debug.apk. The file is already signed with the debug key.
    Each time you change a source file or resource, you must run Ant again in order to package up the latest version of the application.To install and run your application on an emulator, see the following section about Running Your Application.Building in release mode
    When you're ready to release and distribute your application to end-users, you must build your application in release mode. Once you have built in release mode, it's a good idea to perform additional testing and debugging with the final .apk.To build in release mode:Open a command-line and navigate to the root of your project directory.
    Use Ant to compile your project in release mode:
    ant release
    This creates your Android application .apk file inside the project bin/ directory, named <your_DefaultActivity_name>.apk.
    Note: The .apk file is unsigned at this point. You can't install it on an emulator or device until you sign it with your private key.
    Because release mode builds your application unsigned, your next step is to sign it with your private key, in order to distribute it to end-users. To complete this procedure, read Signing Your Applications.Once you have signed your application with a private key, you can install it on an emulator or device as discussed in the following section about Running Your Application. You can also try installing it onto a device from a web server. Simply upload the signed APK to a web site, then load the .apk URL in your Android web browser to download the application and begin installation. (On your device, be sure you have enabled Settings > Applications > Unknown sources.)
      

  5.   

    LZ,你知道怎么用ContentProvider中的openFile方法么?现在我想从网上得到图片,然后把图片保存在SD卡中,再把这个路径和图片名称放到数据库中。我老大就给了个这么个方法,他说用这个方法就行了。纠结~
    其他游客也可以发表下建议和自己的思路,小弟在此谢过……
      

  6.   

    补充一下:这个是在android中的~
      

  7.   

    下午没什么事儿   就看了一下    不要太感动哦  呵呵  开个玩笑   言归正传
    ContentProvider中的openFile方法  可以获得一个ParcelFileDescriptor  可以算是文件的一个描述吧ParcelFileDescriptor 有个方法 
    public static ParcelFileDescriptor   open  (File  file, int mode)
    Create a new ParcelFileDescriptor accessing a given file.还有个方法
    public FileDescriptor   getFileDescriptor  ()    这两个方法是关键  Returns a ParcelFileDescriptor, from which you can obtain a FileDescriptor  for use with FileInputStream, FileOutputStream, etc. This can be used to store large data (such as an image) associated with a particular piece of content. 文档上如是说。
    下面直接上代码
    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    // TODO Auto-generated method stub

    URI uri1 = URI.create("file:///sdcard/HLog.txt");
    Log.i("test", "^^ uri1.getPath = ");
    File file = new File(uri1.getPath());
    ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
    return parcel; 
    }这样就实现了openFile的方法   把一个名为HLog.txt的文件对外提供了在调用端
    try {
             ParcelFileDescriptor descriptor = contentResolver.openFileDescriptor(Uri.parse("content://xxx.xxx.xxx"), "");
             FileInputStream inputStream = new FileInputStream(descriptor.getFileDescriptor());
             FileOutputStream fileOutputStream = new FileOutputStream(new File("/sdcard/aaa.txt"));
             int length = -1;
             byte[] buffer = new byte[1024];
             while((length=inputStream.read(buffer))!=-1){
             fileOutputStream.write(buffer, 0, length);
             }
            
             inputStream.close();
             fileOutputStream.close();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }这样我就得到了contentPervider为我们提供的文件了   至于得到这个文件的流之后 想怎么做  就都看自己了
    至于清单文件里怎么配置contentProvider  我就不写啦~~~
      

  8.   

    l_xd_0214大哥,请问一下,ContentProvider用_data来保存文件的URI,请问一下_data的CRUD应该怎么操作。
    其他游客也可以发表下建议和自己的思路,小弟在此谢过……
      

  9.   

    因为小型的图片可以用二进制的方式保存到数据库(values.put()),但是对大型的图片用把文件放在本地(J2ee是放在本地服务器,android不知放在哪里),数据库放图片的路径,通过图片路径来访问。(这一步应该怎样实现)!其他游客也可以发表下建议和自己的思路,小弟在此谢过……
      

  10.   


    因为小型的图片可以用二进制的方式保存到数据库(values.put()),但是对大型的图片用把文件放在本地(J2ee是放在本地服务器,android不知放在哪里),数据库放图片的路径,通过图片路径来访问。(这一步应该怎样实现)!其他游客也可以发表下建议和自己的思路,小弟在此谢过……
      

  11.   

    ContentProvider  是对外提供了数据的统一访问接口   这些接口自己实现就可以了  调用方不会管你是怎么实现的   举个例子  数据库里要更新一张图片的路径   直接SQL语句就可以了
      

  12.   

    不管是什么图片  直接存在手机里就可以了  我只知道  以前学Oracle的时候  可以存图片进去 android提供的 sqlite3数据小型数据库  个人觉得不适合存二进制文件  也没有必要   房子SDcard里不好么?你问的问题  都是SQL的   自己的图片放到SD卡里  必然要知道存放的路径才可以   把这个路径insert到数据库里  就可以了   对外访问的接口是自己实现的   怎么写都行啊   你存insert一个武藤兰进来  query一个苍井空出去也没人管啊   只要使用的用户不在意就可以 
      

  13.   

    package com.joyque.image;import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.HashMap;
    import com.joyque.image.provider.Reader;
    import com.joyque.image.provider.Reader.Channel;
    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.database.sqlite.SQLiteQueryBuilder;
    import android.net.Uri;
    import android.os.Environment;
    import android.os.ParcelFileDescriptor;
    import android.text.TextUtils;
    import android.util.Log;public class ReaderProvider extends ContentProvider { private static final String TAG = "ReaderProvider";
    private static final String DATABASE_NAME = "reader.db"; private static final int DATABASE_VERSION = 1;
    private static final String CHANNEL_TABLE_NAME = "channel"; private static HashMap<String, String> sChannelProjectionMap; private static final int CHANNEL = 1;
    private static final int CHANNEL_ID = 2; private static final UriMatcher sUriMatcher; static final File EXTERNAL_STORAGE_DIRECTORY = Environment
    .getExternalStorageDirectory(); static final String DATABASE_PATH = "image"; private static boolean useLocal = false; private static String dbPath = EXTERNAL_STORAGE_DIRECTORY + File.separator
    + DATABASE_PATH + File.separator + DATABASE_NAME; private static class DatabaseHelper extends SQLiteOpenHelper {
    DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    if (EXTERNAL_STORAGE_DIRECTORY.canWrite()) {
    File destination = new File(EXTERNAL_STORAGE_DIRECTORY,
    DATABASE_PATH);
    if (!destination.exists()) {
    if (!destination.mkdirs()) {
    useLocal = true;
    dbPath = DATABASE_NAME;
    }
    }
    } else {
    useLocal = true;
    dbPath = DATABASE_NAME;
    }
    } public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + CHANNEL_TABLE_NAME + " ("
    + Channel._ID + " INTEGER PRIMARY KEY," + Channel._DATA
    + " TEXT," + Channel.CHANNEL_ID + " INTEGER,"
    + Channel.NAME + " TEXT," + Channel.DESCRIPTION + " TEXT,"
    + Channel.IMAGE + " TEXT," + Channel.TIMESTAMP + " TEXT"
    + ");");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
    + newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS channel");
    onCreate(db); onCreate(db);
    }
    } private DatabaseHelper mOpenHelper; @Override
    public boolean onCreate() {
    mOpenHelper = new DatabaseHelper(getContext());
    return true;
    } @Override
    public Cursor query(Uri uri, String[] projection, String selection,
    String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); switch (sUriMatcher.match(uri)) {
    case CHANNEL:
    qb.setTables(CHANNEL_TABLE_NAME);
    qb.setProjectionMap(sChannelProjectionMap);
    break; case CHANNEL_ID:
    qb.setTables(CHANNEL_TABLE_NAME);
    qb.setProjectionMap(sChannelProjectionMap);
    qb.appendWhere(Channel._ID + "=" + uri.getPathSegments().get(1));
    break; default:
    throw new IllegalArgumentException("Unknown URI " + uri);
    } String orderBy = null;
    switch (sUriMatcher.match(uri)) {
    case CHANNEL:
    // If no sort order is specified use the default
    if (TextUtils.isEmpty(sortOrder)) {
    orderBy = Reader.Channel.DEFAULT_SORT_ORDER;
    } else {
    orderBy = sortOrder;
    }
    break;
    } SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    Cursor c = qb.query(db, projection, selection, selectionArgs, null,
    null, orderBy); c.setNotificationUri(getContext().getContentResolver(), uri);
    return c;
    } @Override
    public String getType(Uri uri) {
    switch (sUriMatcher.match(uri)) {
    case CHANNEL:
    return Channel.CONTENT_TYPE; case CHANNEL_ID:
    return Channel.CONTENT_ITEM_TYPE; default:
    throw new IllegalArgumentException("Unknown URI " + uri);
    }
    } @Override
    public Uri insert(Uri uri, ContentValues initialValues) {
    // Validate the requested uri
    switch (sUriMatcher.match(uri)) {
    case CHANNEL:
    return insertChannel(uri, initialValues);
    default:
    throw new IllegalArgumentException("Unknown URI " + uri);
    }
    } private Uri insertChannel(Uri uri, ContentValues initialValues) {
    if (sUriMatcher.match(uri) != CHANNEL) {
    throw new IllegalArgumentException("Unknown URI " + uri);
    } if (initialValues == null) {
    return null;
    } ContentValues values = new ContentValues(initialValues); if (values.containsKey(Reader.Channel.CHANNEL_ID) == false) {
    values.put(Reader.Channel.CHANNEL_ID, "");
    } if (values.containsKey(Reader.Channel.NAME) == false) {
    values.put(Reader.Channel.NAME, "");
    } if (values.containsKey(Reader.Channel.DESCRIPTION) == false) {
    values.put(Reader.Channel.DESCRIPTION, "");
    } if (values.containsKey(Reader.Channel.TIMESTAMP) == false) {
    values.put(Reader.Channel.TIMESTAMP, "");
    } if (values.containsKey(Reader.Channel.IMAGE) == false) {
    values.put(Reader.Channel.IMAGE, "");
    } SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    long rowId = db.insert(CHANNEL_TABLE_NAME, Channel.NAME, values);
    if (rowId > 0) {
    Uri channelUri = ContentUris.withAppendedId(
    Reader.Channel.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(channelUri, null); return channelUri;
    }
    throw new SQLException("Failed to insert row into " + uri);
    } /**
     * 对数据表channel,catalog,block,book,chapter的删除操作
     */
    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    int count;
    switch (sUriMatcher.match(uri)) {
    case CHANNEL:
    count = db.delete(CHANNEL_TABLE_NAME, where, whereArgs);
    break; case CHANNEL_ID:
    String channelId = uri.getPathSegments().get(1);
    count = db.delete(CHANNEL_TABLE_NAME,
    Channel._ID
    + "="
    + channelId
    + (!TextUtils.isEmpty(where) ? " AND (" + where
    + ')' : ""), whereArgs);
    break; default:
    throw new IllegalArgumentException("Unknown URI " + uri);
    } getContext().getContentResolver().notifyChange(uri, null);
    return count;
    } /**
     * 对数据表channel,catalog,block,book,chapter的更新操作.
     */
    @Override
    public int update(Uri uri, ContentValues values, String where,
    String[] whereArgs) {
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    int count;
    switch (sUriMatcher.match(uri)) {
    case CHANNEL:
    count = db.update(CHANNEL_TABLE_NAME, values, where, whereArgs);
    break; case CHANNEL_ID:
    String channelId = uri.getPathSegments().get(1);
    count = db.update(CHANNEL_TABLE_NAME, values,
    Channel._ID
    + "="
    + channelId
    + (!TextUtils.isEmpty(where) ? " AND (" + where
    + ')' : ""), whereArgs);
    break;
    default:
    throw new IllegalArgumentException("Unknown URI " + uri);
    } getContext().getContentResolver().notifyChange(uri, null);
    return count;
    } public ParcelFileDescriptor openFile(Uri uri, String mode)
    throws FileNotFoundException {
    if (sUriMatcher.match(uri) != CHANNEL_ID)
    throw new IllegalArgumentException(
    "openFile not supported for directories");
    try {
    String id = uri.getPathSegments().get(1);
    ContentValues values = new ContentValues();
    values.put(Channel._DATA, EXTERNAL_STORAGE_DIRECTORY
    + File.separator + DATABASE_PATH + File.separator 
    + "1.jpg");

    update(uri, values, new String(Channel._ID + "=" + id), null);
    return openFileHelper(uri, mode);
    } catch (FileNotFoundException e) {
    throw new FileNotFoundException();
    }
    } // public ParcelFileDescriptor openFile(Uri uri, String mode)
    // throws FileNotFoundException {
    //
    // if (sUriMatcher.match(uri) != CHANNEL_ID)
    // throw new IllegalArgumentException(
    // "openFile not supported for directories");
    // try {
    // return openFile(uri, mode);
    // } catch (FileNotFoundException e) {
    // throw new FileNotFoundException();
    // }
    //
    // } // public ParcelFileDescriptor openFile(Uri uri, String mode) throws
    // FileNotFoundException {
    //      
    // if (sUriMatcher.match(uri) != CHANNEL_ID) throw new
    // IllegalArgumentException("openFile not supported for directories");
    // try {
    // String id = uri.getPathSegments().get(1);
    // ContentValues values = new ContentValues();
    // values.put(Reader.Channel._DATA, uri.toString() + File.separator +
    // c.getString(0));
    // update(uri,values,new String(Reader.Channel._ID+"="+id),null);
    // return openFile(uri, mode);
    // } catch (FileNotFoundException e) { throw new FileNotFoundException(); }
    //           
    // } static {
    // -- URI匹配器和相应的数据表相匹配.
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(Reader.AUTHORITY, "channel", CHANNEL);
    sUriMatcher.addURI(Reader.AUTHORITY, "channel/#", CHANNEL_ID); // -- 创建相应表列名与相应JavaBean 映射.
    sChannelProjectionMap = new HashMap<String, String>();
    sChannelProjectionMap.put(Channel._ID, Channel._ID);
    sChannelProjectionMap.put(Channel.CHANNEL_ID, Channel.CHANNEL_ID);
    sChannelProjectionMap.put(Channel.NAME, Channel.NAME);
    sChannelProjectionMap.put(Channel.DESCRIPTION, Channel.DESCRIPTION);
    sChannelProjectionMap.put(Channel.TIMESTAMP, Channel.TIMESTAMP);
    sChannelProjectionMap.put(Channel.IMAGE, Channel.IMAGE);
    sChannelProjectionMap.put(Channel._DATA, Channel._DATA);
    }
    }
      

  14.   

    l_xd_0214大哥,真不好意思,麻烦你了,帮我看看,我的其它直都插入了,就是图片的文件夹路径不会插入,请指教。也不你写的调用端的代码在哪个位置取出图片,自己写的openFile方法貌似插入了图片路径,但是进入Sqlite3数据表一查,什么也没有插入。
    (其他游客也可以发表下建议和自己的思路,小弟在此谢过……)
      

  15.   

    最近封闭式开发  很忙  给你提供个思路的  openFile 得到的是一个ParcelFileDescriptor  用它可以得到流  有了流 那就是IO操作了   你要插入文件路径   直接就获得文件的路径  然后当String插入不可以么?   多看看帮助文档  就可以了
      

  16.   

    l_xd_0214大哥,真不好意思,麻烦你了,能不能帮我写一个openFile()方法,上面我写了三个openFile()没有一个可以取出那个流,可能我把流的知识知道太少,谢谢!万分感谢!
      

  17.   

    l_xd_0214大哥,在客户端不是有个getContent().getContentResource().openOutputStream(Uri uri)来取得流不?小弟真不知道那个流怎么和_data数据列联系起来,谢谢。
      

  18.   

    _data列用于插入图片地址的值,在上面哪个地方插入文件的地址再好,和其它的值一起插入可以吗?还是在openFile()方法中插入。
      

  19.   

    多看SDK自带的文档,有很详细的说明的。呵呵