2011-02-04 28 views
10

Tôi có một số yêu cầu để bảo vệ một số dữ liệu nhạy cảm. Các dữ liệu sẽ được tải về dưới dạng PDF từ một URL và lưu lại dưới dạng một tập tin cá nhân ứng dụng bằng cách sử dụng đoạn mã sau:XEM ý định từ URI của nhà cung cấp nội dung?

public File downloadPDF(final Context fileContext, Uri reportUri, final String fileName) 
{ 
    try 
    { 
     HttpGet get = new HttpGet(reportUri.toString()); 

     File file = httpClient.execute(get, new ResponseHandler<File>() 
     { 
      @Override 
      public File handleResponse(HttpResponse response) throws ClientProtocolException, IOException 
      { 
       if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) 
       { 
        response.getEntity().writeTo(fileContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE)); 
        return fileContext.getFileStreamPath(fileName); 
       } 
       return null; 
      } 
     }); 

     return file; 
    } 
    catch (IOException e) 
    { 
     Log.e(TAG, "Unable to download report.", e); 
    } 

    return null; 
} 

Bây giờ, những gì tôi muốn làm là thay đổi này để sử dụng Context.MODE_PRIVATE và tạo ra một ContentProvider để ứng dụng của tôi có toàn quyền kiểm soát việc chia sẻ tệp này với trình đọc PDF như Adobe Reader. Điều này có thể không? Tôi hiện đang sử dụng mã như sau để chuyển URI báo cáo cho trình đọc PDF được định cấu hình hiện tại.

// Fire up a PDF viewer intent for the URL. 
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    intent.setDataAndType(uri, "application/pdf"); 
    startActivity(intent); 

Có thể cùng một công việc thông qua URI kiểu ContentProvider không? Một nội dung: // URI của gói/fileid? Tôi sẽ cố gắng tăng đột biến vào ngày mai để xem liệu tôi có thể, nhưng nếu có ai biết rằng chỉ có tệp: // URI được cho phép, nó sẽ thực sự hữu ích.


CẬP NHẬT

tôi đã có thể giải quyết vấn đề của tôi một cách thỏa đáng bằng cách thực hiện một lớp con ContentProvider với phương pháp sau đây ghi đè:

@Override 
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException 
{ 
    // The filename is the path in the URI without the initial slash. 
    String fileName = uri.getPath().substring(1); 
    File file = getContext().getFileStreamPath(fileName); 
    return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); 
} 

Sau đó, khi tôi bắn ra mục đích xem, nó được viết lại như sau:

Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
Uri uri = Uri.withAppendedPath(Uri.parse("content://providername/"),filePath); 
intent.setData(uri); 
startActivity(intent); 

Và trong trường hợp của tôi, tôi sử dụng Adobe Reader, thực hiện đúng việc tải từ content:// URI.

Trả lời

4

Có thể cùng một công việc thông qua URI kiểu ContentProvider không? Một nội dung: // URI của gói/fileid?

Nên. Bạn cần phải có số trả lại ContentProviderapplication/pdf cho getType() của mình. Và, có thể một số trình đọc PDF sẽ không xử lý các giá trị content://Uri.

Những gì bạn có thể làm là làm cho ContentProvider, sau đó sử dụng PackageManager để xem nếu bất cứ điều gì sẽ hiểu ACTION_VIEWIntent trên content://Uri của bạn. Nếu một cái gì đó phản ứng, bạn đã thiết lập. Nếu không, bạn có thể quay trở lại để làm cho tệp có thể đọc được trên thế giới và sử dụng triển khai hiện tại của bạn. Hoặc, vì việc thay đổi tệp thành có thể đọc được trên thế giới có thể là nỗi đau, bạn có thể chạy thử nghiệm sớm (ví dụ: khi ứng dụng của bạn bắt đầu) với một số mẩu ảnh Uri hỗ trợ ContentProvider của bạn, vì vậy bạn sẽ biết nên đi theo lộ trình nào tải xuống của bạn.

+0

Cảm ơn rất nhiều. Tôi dự định dành buổi sáng của mình làm việc trên một bằng chứng về khái niệm để xem liệu 'nội dung: //' URI có được chấp nhận bởi trình đọc PDF mà tôi thường sử dụng hay không. Tôi không biết về việc sử dụng 'PackageManager' này, vì vậy tôi sẽ đọc về nó. – Thorinside

+1

Vâng, có vẻ như đó là những gì đang xảy ra.Tôi nhìn vào 'nguồn' cho Adobe Reader để xem liệu nó có sử dụng Trình giải quyết nội dung trong trường hợp nội dung 'VIEW nội dung: // Intent' và có vẻ như nó thực sự sẽ xảy ra. Tôi đang cố gắng tìm ra lý do tại sao ContentProvider của tôi không được gọi lại. – Thorinside

+0

Được rồi, tôi đã chỉ ra rằng tôi cần ghi đè phương thức openFile trên cá thể ContentProvider của mình để chặn yêu cầu của Adobe Reader đối với luồng đầu vào. Tôi được khuyến khích. – Thorinside

1

Không cung cấp nội dung không bảo vệ file

Trong thực tế có lẽ là điều đầu tiên mà ứng dụng có thể làm với một tập tin từ một nhà cung cấp nội dung là tạo một bản sao tạm thời trong dir cache của nó. Tôi nghĩ bạn nên xem lại điều này.

Các vấn đề liên quan