11

起動モードを「singleInstance」にしたときに、MYApp で電子メールを開く際に問題に直面しています。

メールの添付ファイルからファイル名を読み取り、画面に表示するサンプル Android プロジェクトを添付しました。onCreate の場合は問題なく動作しますが、アプリの起動モードが singleInstance の場合、onNewIntent でエラーがスローされます。

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");
    }
}

}

Androidマニフェスト

<?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>

再現手順 1) デバイスに apk をインストールします。2) デバイスの Gmail ネイティブ アプリに移動し、添付ファイル (オフィス ドキュメント) を開いて表示します。3) LaunchMode アプリを選択してアクションを完了します。4) LaunchMode アプリは画面にファイル名を表示します。

これは初めて (onCreate フロー) は正常に動作しますが、このアプリがバックグラウンドで切り替えられ、再度 2、3、4 の手順を試すと、エラーでアプリがクラッシュします。

E/DatabaseUtils(30615): java.lang.SecurityException: Permission Denial: reading com.google.android.gm.provider.MailProvider uri content://gmail-ls/qoconnect@gmail.com/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

これを修正する必要があるのは、アプリケーションの単一のインスタンスが必要であり、電子メールの添付ファイル名も取得する必要があるためです。ここで何か不足している場合はお知らせください。

ここでの私の質問は、onCreate のフローで機能し、onNewIntent の場合は機能しない理由です。

注: 1) 2.x 携帯電話で正常に動作します。 2) シングルトップ起動モードで正常に動作します。3) Gmail アプリの更新。ここにリンク:

4

2 に答える 2

5

インテントを受け取ったときにファイル名を読み取るための URI アクセス許可を取得し、要求したアクセス許可を使用していない可能性があります (READ_GMAILおよびWRITE_GMAIL)。URI パーミッションはアプリケーションが終了するまでしか有効でfinish()はないため、再開しようとするとアクセスできなくなります。

それはあなたの経験と一致しています-意図が新しい場合には機能しますが、古いものでは機能しません。WRITE_GMAILそれは署名の許可だと思いますし、それもそうだと思いますREAD_GMAIL。その場合、できることはあまりありません。 READ_ATTACHMENTあなたが要求するより適切な許可かもしれません。

URI パーミッションの詳細: http://developer.android.com/guide/topics/security/permissions.html#uri

マニフェストからタグを削除してみuses-permissionて、同じ経験があるかどうかを確認してください。intentフラグをチェックして、いつ受信したかを調べることもできます。

checkCallingOrSelfUriPermission(documentUri , Intent.FLAG_GRANT_READ_URI_PERMISSION)

0 が返された場合は、URI パーミッションを使用しています。

于 2012-07-30T15:02:11.063 に答える
0

skoke が言ったように、許可を与えたインテントが新鮮でない場合、つまり、元のアクティビティ インテントでなければならない場合、GMail から読み取ることはできなくなります。あなたの意図がonNewIntentそれからのものである場合、おそらく成功しません。

私の解決策は美しくありませんが、うまくいっているようです。私onResumeはカスタム関数を呼び出して、Gmail コンテンツにアクセスできるかどうかを確認しました。そうでない場合は、ユーザーにメッセージを表示し、アプリを閉じてもう一度やり直すように依頼しました。ねえ、少なくともそれはクラッシュしません。

于 2014-11-27T01:28:37.020 に答える