2012-02-25 21 views
10

Tôi đang gặp sự cố khi mở Email trong MYApp khi tôi thực hiện chế độ khởi chạy thành "singleInstance".Nhận lỗi cho phép java.lang.SecurityException: Quyền từ chối trên thiết bị Android 3.x trong khi nhận được tên tệp đính kèm email

Tôi đã đính kèm dự án Android mẫu đọc tên tệp từ tệp đính kèm email và hiển thị nó trên màn hình. Hoạt động tốt trong trường hợp onCreate nhưng ném lỗi trong onNewIntent khi chế độ khởi chạy ứng dụng là singleInstance.

Launchmode.java

package your.namespace.launchmode; 


public class LaunchModeActivity extends Activity { 
    private static final int OPEN_ACT = 2; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    String name = getAttachmetName(getIntent()); 
    if(null != name) 
    { 
     TextView textv = (TextView) findViewById(R.id.attachmentnm); 
     textv.setText(name); 
    } 
} 

@Override 
protected void onNewIntent(Intent savedInstanceState) 
{ 
    super.onNewIntent(savedInstanceState); 
    String name = getAttachmetName(savedInstanceState); 
    if(null != name) 
    { 
     TextView textv = (TextView) findViewById(R.id.attachmentnm); 
     textv.setText(name); 
    } 
} 


private String getAttachmetName(Intent intent) { 
    final Uri documentUri = intent.getData(); 
    if(null != documentUri){ 
    final String uriString = documentUri.toString(); 
    String documentFilename = null; 


    final int mailIndexPos = uriString.lastIndexOf("/attachments"); 
    if (mailIndexPos != -1) { 
     final Uri curi = documentUri; 
     final String [] projection = new String[] {OpenableColumns.DISPLAY_NAME}; 
     final Cursor cursor = getApplicationContext().getContentResolver().query(curi, projection, null, null, null); 
     if (cursor != null) { 
      final int attIdx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); 
      if (attIdx != -1) { 
       cursor.moveToFirst(); 
       documentFilename = cursor.getString(attIdx);     
      } 
      cursor.close(); 
     } 
    } 
    return documentFilename; 
    } 
    return null; 
} 


@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // TODO Auto-generated method stub 
    super.onActivityResult(requestCode, resultCode, data); 

    if((resultCode == RESULT_OK) && (requestCode == OPEN_ACT)) 
    { 
     Log.d("LaunchMode", "Second activity returned"); 
    } 
} 

}

AndroidManifest

<?xml version="1.0" encoding="UTF-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="your.namespace.launchmode" 
    android:versionCode="1" 
    android:versionName="1.0" > 
    <uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/> 
    <uses-permission android:name="com.google.android.gm.permission.WRITE_GMAIL"/> 
    <uses-permission android:name="com.google.android.providers.gmail.permission.READ_GMAIL"/> 
    <uses-permission android:name="com.google.android.providers.gmail.permission.WRITE_GMAIL"/> 
    <uses-sdk android:minSdkVersion="8" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:label="@string/app_name" 
      android:launchMode="singleInstance" 
      android:name=".LaunchModeActivity" > 
      <intent-filter > 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
      <intent-filter > 
       <action android:name="android.intent.action.VIEW" /> 

       <category android:name="android.intent.category.DEFAULT" /> 
       <!-- docx --> 
       <data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" /> 
       <!-- xlsx --> 
       <data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /> 
       <!-- pptx --> 
       <data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" /> 
       <data android:mimeType="application/vnd.ms-excel" /> 
       <data android:mimeType="application/msword" /> 
       <data android:mimeType="application/vnd.ms-powerpoint" /> 
       <data android:mimeType="text/plain" /> 
      </intent-filter> 
     </activity> 
    </application> 
</manifest> 

Các bước để tạo 1) Cài đặt APK trên thiết bị. 2) Đi tới ứng dụng gốc gmail trên thiết bị, mở bất kỳ tệp đính kèm nào (tài liệu văn phòng) để xem. 3) Chọn ứng dụng LaunchMode để hoàn thành hành động. 4) LaunchMode ứng dụng sẽ hiển thị tên tập tin trên màn hình.

này hoạt động tốt cho lần đầu tiên (dòng chảy onCreate) nhưng khi ứng dụng này là công tắc ở chế độ nền và một lần nữa tôi cố gắng 2,3,4 bước .. treo ứng dụng với lỗi

E/DatabaseUtils(30615): java.lang.SecurityException: Permission Denial: reading com.google.android.gm.provider.MailProvider uri content://gmail-ls/[email protected]/messages/5/attachments/0.2/BEST/false from pid=32657, uid=10058 requires com.google.android.gm.permission.READ_GMAIL 
E/DatabaseUtils(30615):  at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:309) 
E/DatabaseUtils(30615):  at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:178) 
E/DatabaseUtils(30615):  at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:111) 
E/DatabaseUtils(30615):  at android.os.Binder.execTransact(Binder.java:339) 
E/DatabaseUtils(30615):  at dalvik.system.NativeStart.run(Native Method) 
D/AndroidRuntime(32657): Shutting down VM 

tôi cần phải sửa lỗi này vì, tôi cần phải có một ứng dụng đơn lẻ và cũng sẽ nhận được tên tệp đính kèm email. Vui lòng cho tôi biết Nếu tôi thiếu điều gì đó ở đây.

Câu hỏi của tôi ở đây là lý do tại sao nó hoạt động trong dòng chảy của onCreate và nó sẽ không làm việc trong trường hợp onNewIntent

Lưu ý: 1) Hoạt động tốt với điện thoại 2.x 2) Hoạt động tốt với đơn mode ra mắt đầu. 3) Một số cập nhật về ứng dụng Gmail. link here:

Trả lời

5

Bạn có thể có quyền URI để đọc tên tệp khi bạn nhận được ý định và không sử dụng các quyền mà bạn đã yêu cầu (READ_GMAILWRITE_GMAIL). Quyền URI chỉ hợp lệ cho đến khi ứng dụng của bạn finish() es, do đó bạn sẽ không có quyền khi bạn cố gắng tiếp tục.

Điều đó phù hợp với trải nghiệm của bạn - nó hoạt động khi mục đích là mới, nhưng không hoạt động khi mục đích cũ. Tôi nghĩ rằng WRITE_GMAIL là một sự cho phép chữ ký và tôi đoán rằng READ_GMAIL là tốt. Trong trường hợp đó, không có nhiều bạn có thể làm. READ_ATTACHMENT có thể là sự cho phép phù hợp hơn để bạn yêu cầu.

Thông tin thêm về quyền URI: http://developer.android.com/guide/topics/security/permissions.html#uri

Cố gắng loại bỏ các uses-permission thẻ từ biểu hiện của bạn và xem nếu bạn có kinh nghiệm tương tự. Bạn cũng có thể thử để kiểm tra các intent khi bạn nhận được nó bằng cách kiểm tra lá cờ của nó.

checkCallingOrSelfUriPermission(documentUri , Intent.FLAG_GRANT_READ_URI_PERMISSION) 

Nếu bạn nhận được 0 trả lại, bạn đã sử dụng quyền URI.

0

Giống như skoke đã nói, bạn không còn có thể đọc từ Gmail nếu ý định cho phép của bạn không được làm mới, tức là, nó phải là mục đích hoạt động ban đầu.Nếu ý định của bạn là từ onNewIntent thì có thể nó sẽ không thành công.

Giải pháp của tôi không đẹp nhưng có vẻ đang hoạt động. Trong số onResume, tôi đã gọi hàm tùy chỉnh để xem liệu tôi có thể truy cập nội dung Gmail hay không. Nếu không, tôi đã hiển thị cho người dùng một tin nhắn và yêu cầu họ đóng ứng dụng và thử lại. Hey, ít nhất nó không sụp đổ.

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