2015-07-22 198 views

回答

0

這是我最後使用的方式,希望這會幫助別人。 新增供應商清單文件

 <provider 
     android:name=".AssetsProvider" 
     android:authorities="yourpackage.provider" 
     android:exported="true" 
     android:grantUriPermissions="true" 
     android:readPermission="yourpermission"></provider> 

    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" 
     android:screenOrientation="landscape"> 
     <intent-filter> 
      <action android:name="android.intent.action.PICK" /> 

      <category android:name="android.intent.category.DEFAULT" /> 
      <category android:name="android.intent.category.OPENABLE" /> 

      <data android:mimeType="application/octet-stream" /> 
     </intent-filter> 
    </activity> 

繼inProvider活動的onCreate(),以獲得資產列表並返回uriArray給調用者(消費者應用程序)

String[] assetFilesList = null; 
    // Get Asset Mangaer 
    AssetManager assetManager = getAssets(); 
    try { 
     assetFilesList = assetManager.list(); 
    } catch (IOException e) { 
     Log.e(TAG, Log.getStackTraceString(e)); 
    } 
    // Set up an Intent to send back to apps that request files 
    mResultIntent = new Intent("yourpackage.ACTION_SEND_MULTIPLE"); 
    // new Uri list 
    ArrayList<Uri> uriArrayList = new ArrayList<>(); 
    // Set the Activity's result to null to begin with 
    setResult(Activity.RESULT_CANCELED, null); 

    Uri fileUri; 
    if (assetFilesList != null) { 
     for (String currFile : assetFilesList) { 
      Log.i(TAG, "Adding File " + currFile); 
      // parse and create uri 
      fileUri = Uri.parse("content://" + this.getPackageName() + ".provider/" + currFile); 
      // add current file uri to the list 
      uriArrayList.add(fileUri); 
     } 
    } 
    else { 
     Log.e(TAG, "files array is pointing to null"); 
    } 

    if (uriArrayList.size() != 0) { 
     // Put the UriList Intent 
     mResultIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriArrayList); 
     mResultIntent.setType("application/octet-stream"); 
     // Set the result 
     this.setResult(Activity.RESULT_OK, mResultIntent); 
    } else { 
     // Set the result to failed 
     mResultIntent.setDataAndType(null, ""); 
     this.setResult(RESULT_CANCELED, mResultIntent); 
    } 
    // Finish Activity and return Result to Caller 
    finish(); 

我的資產提供者類,我還沒有實現查詢,更新等...因爲這些不是我的情況所必需的。

public class AssetsProvider extends ContentProvider { 
static final String TAG = "AssetsProvider"; 

@Override 
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { 
    Log.v(TAG, "AssetsGetter: Open asset file " + uri.toString()); 
    AssetManager am = getContext().getAssets(); 
    String file_name = uri.getLastPathSegment(); 
    if (file_name == null) 
     throw new FileNotFoundException(); 
    AssetFileDescriptor afd = null; 
    try { 
     afd = am.openFd(file_name); 
    } catch (IOException e) { 
     Log.e(TAG, Log.getStackTraceString(e)); 
    } 
    return afd; 
} 

@Override 
public String getType(Uri p1) { 
    // TODO: Implement this method 
    return null; 
} 

@Override 
public int delete(Uri p1, String p2, String[] p3) { 
    // TODO: Implement this method 
    return 0; 
} 

@Override 
public Cursor query(Uri p1, String[] p2, String p3, String[] p4, String p5) { 
    // TODO: Implement this method 
    return null; 
} 

@Override 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal) { 
    // TODO: Implement this method 
    return super.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal); 
} 

@Override 
public Uri insert(Uri p1, ContentValues p2) { 
    // TODO: Implement this method 
    return null; 
} 

@Override 
public boolean onCreate() { 
    // TODO: Implement this method 
    return false; 
} 

@Override 
public int update(Uri p1, ContentValues p2, String p3, String[] p4) { 
    // TODO: Implement this method 
    return 0; 
} 
} 

搖籃構建選項,以避免資產的文件壓縮(這是文件的類型,我在資產)

aaptOptions { 
    noCompress '.json' , '.xls' 
} 

繼在消費活動

在的onCreate() - setPackage()是必需的,因爲我們要將ACTION_PICK發送到特定應用程序

 Intent mRequestFileIntent = new Intent(Intent.ACTION_PICK); 
     mRequestFileIntent.setPackage("yourAssetsProviderpackage"); 
     mRequestFileIntent.setType("application/octet-stream"); 
     try { 
      startActivityForResult(mRequestFileIntent, 0); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      Toast.makeText(this, "Install Assets Provider app before start", Toast.LENGTH_LONG).show(); 
      finish(); 
     } 

新增覆蓋方法onActivityResult()

public void onActivityResult(int requestCode, int resultCode, 
          Intent returnIntent) { 
    // If the selection didn't work 
    if (resultCode != Activity.RESULT_OK) { 
     // Exit without doing anything else 
     Log.e(TAG, "Activity returned fail"); 
    } else { 
     // get array list 
     ArrayList<Uri> uriArrayList = returnIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); 
     // create directory in internal storage to store the assets from uri list 
     String toPath = this.getFilesDir().getPath(); 
     if (uriArrayList != null) { 
      AssetFileDescriptor mInputAFD; 
      for (int i = 0; i < uriArrayList.size(); i++) { 
       // Get the file's content URI 
       Uri returnUri = uriArrayList.get(i); 
       try { 
        mInputAFD = getContentResolver().openAssetFileDescriptor(returnUri, "r"); 
        // Get file name 
        String fileName = returnUri.getLastPathSegment(); 
        Log.i(TAG, "URI " + returnUri.toString() + " fileName " + fileName); 
        // Create dest filename and copy 
        File dest = new File(toPath + "/" + fileName); 
        copyRaw(mInputAFD, dest); 
       } catch (Exception e) { 
        Log.e(TAG, Log.getStackTraceString(e)); 
        // Break loop at first exception 
        break; 
       } 
      } 
     } 
    } 
} 

CopyRaw方法使用AssetFileDescriptor

public void copyRaw(AssetFileDescriptor fd, File destinationFile) throws IOException { 

    FileChannel sourceChannel = new FileInputStream(fd.getFileDescriptor()).getChannel(); 
    FileChannel destinationChannel = new FileOutputStream(destinationFile).getChannel(); 

    sourceChannel.transferTo(fd.getStartOffset(), fd.getLength(), destinationChannel); 
} 

添加權限消費清單文件

<uses-permission android:name="yourpermission" />