2012-02-29 8 views
15

私はちょうど私のアプリのためのウィジェットを実装しました。それは私のContentProviderを通してデータベースからデータを取得します。私は(違いを確認していないようです)私のマニフェストで私自身の読み取り/書き込み権限、私はそれらを使用する状態を定義し、コンテンツプロバイダでそれらを必要とする:コンテンツプロバイダのウィジェット。 ReadPermissionを使用することは不可能ですか?

<!-- Define my permissions for the provider --> 
<permission 
    android:name="com.nononsenseapps.notepad.permissions.read" 
    android:description="@string/permission_read_desc" 
    android:label="@string/permission_read_label" 
    android:permissionGroup="android.permission-group.PERSONAL_INFO" 
    android:protectionLevel="normal" /> 
<permission 
    android:name="com.nononsenseapps.notepad.permissions.write" 
    android:description="@string/permission_write_desc" 
    android:label="@string/permission_write_label" 
    android:permissionGroup="android.permission-group.PERSONAL_INFO" 
    android:protectionLevel="normal" /> 
...... 
<uses-permission android:name="com.nononsenseapps.notepad.permissions.read" /> 
<uses-permission android:name="com.nononsenseapps.notepad.permissions.write" /> 
<uses-permission android:name="android.permission.BIND_REMOTEVIEWS" /> 
...... 
<provider 
     android:name=".NotePadProvider" 
     android:authorities="com.nononsenseapps.NotePad" 
     android:enabled="true" 
     android:exported="true" 
     android:label="@string/app_name" 
     android:readPermission="com.nononsenseapps.notepad.permissions.read" 
     android:syncable="true" 
     android:writePermission="com.nononsenseapps.notepad.permissions.write" > 
     <grant-uri-permission android:pathPattern=".*" /> 
    </provider> 

私はを通じて自分のウィジェットを更新します(ウィジェットのチュートリアルごとなど)Service:だからここ

/** 
* This is the service that provides the factory to be bound to the collection 
* service. 
*/ 
public class ListWidgetService extends RemoteViewsService { 

@Override 
public RemoteViewsFactory onGetViewFactory(Intent intent) { 
    return new StackRemoteViewsFactory(this.getApplicationContext(), intent); 
} 
} 

/** 
* This is the factory that will provide data to the collection widget. 
*/ 
class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { 

public StackRemoteViewsFactory(Context context, Intent intent) { 
    mContext = context; 
    observer = new ListChecker(null); 
    mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 
      AppWidgetManager.INVALID_APPWIDGET_ID); 
} 
public void onDataSetChanged() { 
    Log.d(TAG, "onDataSetChanged"); 
    // Refresh the cursor 
    if (mCursor != null) { 
     mCursor.close(); 
    } 

    // Get widget settings 
    SharedPreferences settings = mContext.getSharedPreferences(
      ListWidgetConfigure.getSharedPrefsFile(mAppWidgetId), 
      mContext.MODE_PRIVATE); 
    if (settings != null) { 
     String listWhere = settings.getString(ListWidgetConfigure.LIST_WHERE, null); 
     listId = settings.getLong(ListWidgetConfigure.LIST_ID, -1); 
     String sortOn = settings.getString(ListWidgetConfigure.SORT_ON, NotePad.Notes.ALPHABETIC_ASC_ORDER); 

     mCursor = mContext.getContentResolver().query(
       NotePadProvider.CONTENT_VISIBLE_URI, PROJECTION, listWhere, null, 
       sortOn); 
    } 
} 
} 

を問題だ:

<!-- List Widget --> 
    <receiver android:name="com.nononsenseapps.notepad.widget.ListWidgetProvider" > 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
     </intent-filter> 

     <meta-data 
      android:name="android.appwidget.provider" 
      android:resource="@xml/listwidgetinfo" /> 
    </receiver> 

    <service 
     android:name="com.nononsenseapps.notepad.widget.ListWidgetService" 
     android:exported="false" 
     android:permission="android.permission.BIND_REMOTEVIEWS" /> 

ひいてはそのServiceは(含まれていないコードの束と)、この処理を行います。ウィジェットをホームスクリーンに追加すると、onDataSetChanged()メソッドの内部でSecurityExceptionがすぐにスローされ、プロバイダをクエリしようとします。これは、ホーム画面が私のコンテンツプロバイダを読む許可を保持していないためと思われる。私の直感は、自分のアプリが許可を持っているので問題にならないだろうということでした。サービスは明らかに私のアプリの一部です。

プロバイダからReadPermission要件を削除すると、すべてが美しく機能します。しかし、セキュリティ上の問題のように思えます。ユーザーが何も承認しなくても、どのアプリもプロバイダにアクセスできるからです。

ウィジェットでReadPermissionを持つプロバイダを使用する方法はありますか?または、セキュリティで保護されていない輸出業者を強制的に使用していますか?

+0

私はまったく同じ問題を抱えています、あなたはまだ解決策を見つけましたか?もしそうなら、あなたはそれをどのように修正したか答えてください。 –

+0

悲しいことに、私はちょうど必要な権限を削除したので、解決策は見つかりませんでした:( –

+0

また、この問題があります... – JMRboosties

答えて

13

回答はhereでした。クレジットはKostya Vasilyevになります。

実際にはコンテキストは正しくありますが、間違ったプロセスにバインドされています。

ので、キーがこれを行うことです。

public void onDataSetChanged() { 
    // Revert back to our process' identity so we can work with our 
    // content provider 
    final long identityToken = Binder.clearCallingIdentity(); 

    // Update your cursor or whaterver here 
    // ... 

    // Restore the identity - not sure if it's needed since we're going 
    // to return right here, but it just *seems* cleaner 
    Binder.restoreCallingIdentity(identityToken); 
} 
+0

私はさらに調査し、解決策を見つけることができました!完璧な応答。これにより、contentproviderに対する読み取り/書き込みアクセス権を設定せずに、「false」に設定されたエクスポートでのみ問題を解決できます。 –

0

おそらく、あなたがウィジェットのコンテキストを使用しているためです。これはホーム画面のコンテキストになります。コードで次の行を試してください:

mCursor = ListWidgetService.this.getContentResolver().query(
      NotePadProvider.CONTENT_VISIBLE_URI, PROJECTION, listWhere, null, 
      sortOn); 

mContext.の置き換え方法に注意してください。サービスは、独自のコンテキストであり、マニフェストが与えられれば、適切なアクセス許可が必要です。

+0

実際には、コードを見れば、RemoteViewsFactoryに渡されるコンテキストはあなたの提案とまったく同じです。 –

+0

確かに、あなたは正しいです、私はそれを逃したか分からない:)しかし、私はそれがとにかく右のトラックにあなたを置くことがうれしいです:) –

関連する問題