MimeTypes.java
package ******;
import android.net.Uri;
import android.content.ContentResolver;
import java.util.Arrays;
import java.util.Set;
import java.util.List;
public final class MimeTypes {
private MimeTypes() {}
public static String[] splitMimeType(String mimeType) {
final String[] groups = mimeType.split("/");
if (groups.length != 2 || groups[0].isEmpty() || groups[1].isEmpty()) {
return null;
}
return groups;
}
public static String findCommonMimeType(List<String> mimeTypes) {
String[] commonType = splitMimeType(mimeTypes.get(0));
if (commonType == null) {
return "*/*";
}
for (int i = 1; i < mimeTypes.size(); i++) {
String[] type = mimeTypes.get(i).split("/");
if (type.length != 2) continue;
if (!commonType[1].equals(type[1])) {
commonType[1] = "*";
}
if (!commonType[0].equals(type[0])) {
commonType[0] = "*";
commonType[1] = "*";
break;
}
}
return commonType[0] + "/" + commonType[1];
}
}
DownloadScanner.java
package ******;
public class DownloadScanner implements MediaScannerConnectionClient {
private static final String TAG = "DownloadScanner";
private static final long SCAN_TIMEOUT = MINUTE_IN_MILLIS;
private final Context mContext;
private final MediaScannerConnection mConnection;
private static class ScanRequest {
public final String path;
public final String mimeType;
public final long requestRealtime;
public ScanRequest( String path, String mimeType) {
this.path = path;
this.mimeType = mimeType;
this.requestRealtime = SystemClock.elapsedRealtime();
}
public void exec(MediaScannerConnection conn) {
conn.scanFile(path, null);
}
}
private HashMap<String, ScanRequest> mPending = new HashMap<>();;
private CountDownLatch mLatch;
public DownloadScanner(Context context) {
mContext = context;
mConnection = new MediaScannerConnection(context, this);
}
public static void requestScanBlocking(Context context, String path, String mimeType) {
final DownloadScanner scanner = new DownloadScanner(context);
scanner.mLatch = new CountDownLatch(1);
scanner.requestScan(new ScanRequest(path, mimeType));
try {
scanner.mLatch.await(SCAN_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
scanner.shutdown();
}
}
/**
* Check if requested scans are still pending. Scans may timeout after an
* internal duration.
*/
public boolean hasPendingScans() {
synchronized (mConnection) {
if (mPending.isEmpty()) {
return false;
} else {
// Check if pending scans have timed out
final long nowRealtime = SystemClock.elapsedRealtime();
for (ScanRequest req : mPending.values()) {
if (nowRealtime < req.requestRealtime + SCAN_TIMEOUT) {
return true;
}
}
return false;
}
}
}
/**
* Request that given {@link DownloadInfo} be scanned at some point in
* future. Enqueues the request to be scanned asynchronously.
*
* @see #hasPendingScans()
*/
public void requestScan(ScanRequest req) {
Log.v(TAG, "requestScan() for " + req.path);
synchronized (mConnection) {
mPending.put(req.path, req);
if (mConnection.isConnected()) {
req.exec(mConnection);
} else {
mConnection.connect();
}
}
}
public void shutdown() {
mConnection.disconnect();
}
@Override
public void onMediaScannerConnected() {
synchronized (mConnection) {
for (ScanRequest req : mPending.values()) {
req.exec(mConnection);
}
}
}
@Override
public void onScanCompleted(String path, Uri uri) {
final ScanRequest req;
synchronized (mConnection) {
req = mPending.remove(path);
}
if (req == null) {
Log.w(TAG, "Missing request for path " + path);
return;
}
// File got deleted while waiting for it to be mediascanned.
if (uri == null) {
if (mLatch != null) {
mLatch.countDown();
}
return;
}
if (mLatch != null) {
mLatch.countDown();
}
Log.v(TAG, "onScanCompleted path " + path + " uri:" + uri);
DocumentInfo item = new DocumentInfo();
ContentResolver cr = mContext.getContentResolver();
item.setDerivedUri(uri);
item.setMimeType(cr.getType(uri));
ShareManager.getInstance(mContext).addDoc(item);
}
}
DocumentInfo.java
package ******;
import android.net.Uri;
public class DocumentInfo {
private static final String TAG = "DocumentInfo";
public Uri derivedUri;
public String mimeType;
public DocumentInfo() {
}
public DocumentInfo(Uri derivedUri, String mimeType) {
this.derivedUri = derivedUri;
this.mimeType = mimeType;
}
public Uri getDerivedUri() {
return derivedUri;
}
public void setDerivedUri(Uri derivedUri) {
this.derivedUri = derivedUri;
}
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
}
ShareManager.java
public class ShareManager {
private static String TAG = "share";
private static ShareManager instance;
private Context mContext;
List<DocumentInfo> mDocs = new ArrayList<DocumentInfo>();
private ShareManager(Context context) {
mContext = context;
}
public void addDoc(DocumentInfo doc) {
mDocs.add(doc);
Log.d(TAG, "addDoc doc:" + doc);
if (mDocs.size() == mFileNum) {
startShareApp(mDocs);
}
}
public static ShareManager getInstance(Context context) {
if (instance == null) {
instance = new ShareManager(context);
}
return instance;
}
public void shareFiles(ArrayList<String> filePaths) {
if (filePaths != null) {
final int N = filePaths.size();
mFileNum = N;
for (int i = 0; i < N; i++) {
String filePath = filePaths.get(i);
DownloadScanner.requestScanBlocking(mContext, filePath, "");
}
}
}
public void startShareApp(List<DocumentInfo> docs) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();
Intent intent;
if (docs.size() == 1) {
intent = new Intent(Intent.ACTION_SEND);
DocumentInfo doc = docs.get(0);
intent.setType(doc.mimeType);
intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri);
} else if (docs.size() > 1) {
intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
final ArrayList<String> mimeTypes = new ArrayList<>();
final ArrayList<Uri> uris = new ArrayList<>();
for (DocumentInfo doc : docs) {
mimeTypes.add(doc.mimeType);
uris.add(doc.derivedUri);
}
intent.setType(MimeTypes.findCommonMimeType(mimeTypes));
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
} else {
mFileNum = 0;
mDocs.clear();
return;
}
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
Intent chooserIntent = Intent.createChooser(
intent, "").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(chooserIntent);
mFileNum = 0;
mDocs.clear();
}
}
使用方法
**ShareManager.getInstance(context).shareFiles(filePaths,);**