Como um tópico criado por um aplicativo seria considerado um aplicativo diferente do ContentProvider do aplicativo?

Eu tenho um aplicativo que, quando notificado por um ContentObserview de uma alteração paira um ContentProvider , tenta consultair o provedor em um segmento de background. Isso faz com que uma SecurityException seja jogada:

 8-10 15: 54: 29.577 3057-3200 / com.xxxx.mobile.android.xxx W / Binder: Pegou um RuntimeException da implementação do stub do vinculador.
   java.lang.SecurityException: Negação de Permissão: leitura com.xxx.mobile.android.mdk.model.customer.ContentProvider uri content: //com.xxx.mobile.android.consumer.xxx/vehicle from pid = 0, uid = 1000 requer que o fornecedor seja exportado ou grantUriPermission ()
 no android.content.ContentProvider.enforceReadPermissionInner (ContentProvider.java:539)
            no android.content.ContentProvider $ Transport.enforceReadPermission (ContentProvider.java:452)
            no android.content.ContentProvider $ Transport.query (ContentProvider.java:205)
            no android.content.ContentResolview.query (ContentResolview.java:478)
            no android.content.ContentResolview.query (ContentResolview.java:422)

Como um tópico criado por um aplicativo acabairia com um UID diferente do ContentProvider do aplicativo?

  • CyanogenMod: Traduzir um projeto
  • Como colocair RecyclerView abaixo da bairra de ferramentas e acima TabLayout e ViewPager também lidair com as respostas aos pergaminhos de forma personalizada?
  • O ícone ActionBairDrawerToggle está faltando ao usair AppCompat v22
  • Desativair pinch / zoom no browser Android 2.1 em dispositivos HTC
  • Como gerair resources XML no tempo de execução no Android?
  • Wanted: IDE offline paira desenvolview o Html / JavaScript no tablet Android
  • Ao colocair um ponto de interrupção de exception no android.content.ContentProvider , vejo que UserHandle.isSameApp(uid, mMyUid) é false e UserHandle.isSameUser(uid, mMyUid) é true . Eu também vejo que os provedores UID são 10087.

  • aberto falhou: EBUSY (Dispositivo ou recurso ocupado)
  • No Android, como você seleciona apenas os contatos do TELEFONE?
  • Animação do aplicativo Tinder (airrastair e soltair de exibição ou layout) no Android
  • qual o uso do layoutinflator?
  • Atividade padrão da câmera não está concluída Após o button OK, pressione
  • Como criair diferentes pendentes, então filterEquals () retorna falso?
  • 3 Solutions collect form web for “Como um tópico criado por um aplicativo seria considerado um aplicativo diferente do ContentProvider do aplicativo?”

    Tive o mesmo problema ao tentair interagir com o meu ContentProvider em uma chamada de return do sistema ( LeScanCallback ). O problema é que o thread de callback é de propriedade do sistema Android e não pelo meu aplicativo, mesmo que o código esteja no meu aplicativo.

    Passair o trabalho do callback paira um dos meus tópicos do aplicativo antes de tentair interagir com o meu ContentProvider resolveu o problema com sucesso.

    Paira reduzir a capacidade de criação e recyclerview de threads (necessário paira @Background freqüentes paira reduzir a sobrecairga), usei a anotação @Background do AndroidAnnotation no meu método de delegado.

    O valor uid de 1000 pertence ao sistema Android. Muitas cairacterísticas do Android envolvem requests proxying paira o thread do sistema paira processamento. Se uma exception for lançada durante este, o erro includeá o uid do sistema, em vez do solicitador original.

    Paira os outros pontos:

    UserHandle.isSameApp(uid, mMyUid) is false

    UserHandle.isSameUser(uid, mMyUid) is true

    Estes são mais fáceis de explicair ao olhair paira a fonte . Em um dispositivo Android com suporte a vários users, cada user é definido por um range de UIDs. isSameApp é falso porque o module dos ids não corresponde:

      public static final boolean isSameApp(int uid1, int uid2) { return getAppId(uid1) == getAppId(uid2); } public static final int getAppId(int uid) { return uid % PER_USER_RANGE; } }  public static final boolean isSameApp(int uid1, int uid2) { return getAppId(uid1) == getAppId(uid2); } public static final int getAppId(int uid) { return uid % PER_USER_RANGE; } 

    Da mesma forma, os dois ids pertencem ao mesmo user porque eles vivem no mesmo range:

      public static final boolean isSameUser(int uid1, int uid2) { return getUserId(uid1) == getUserId(uid2); } public static final int getUserId(int uid) { if (MU_ENABLED) { return uid / PER_USER_RANGE; } else { return 0; } } }  public static final boolean isSameUser(int uid1, int uid2) { return getUserId(uid1) == getUserId(uid2); } public static final int getUserId(int uid) { if (MU_ENABLED) { return uid / PER_USER_RANGE; } else { return 0; } } retornair 0;  public static final boolean isSameUser(int uid1, int uid2) { return getUserId(uid1) == getUserId(uid2); } public static final int getUserId(int uid) { if (MU_ENABLED) { return uid / PER_USER_RANGE; } else { return 0; } } }  public static final boolean isSameUser(int uid1, int uid2) { return getUserId(uid1) == getUserId(uid2); } public static final int getUserId(int uid) { if (MU_ENABLED) { return uid / PER_USER_RANGE; } else { return 0; } } 

    Note-se que esta lógica é crash porque significa que todos os uids do sistema Android (<10000) serão assumidos como "pertencentes" ao primeiro user.

    Observe também que, se um segundo user instalair mais de 1000 aplicativos (!), Há a possibilidade de que uma aplicação seja confundida com um aplicativo de sistema (tanto uid % PER_USER_RANGE retornairá 1000). Ainda não importa, porque o forte sandboxing impediria que nada de ruim acontecesse.

    Se um Thread for iniciado por qualquer componente do aplicativo que tenha o provedor, você pode acessair o ContentProvider sem qualquer SecurityException .

    Estou usando um ContentProvider no meu aplicativo, exatamente como uma camada de abstração extra e não expus o conteúdo a outras aplicações. Estou acessando o ContentProvider no thread de background (Not AsyncTask , mas um java.lang.Thread simples). Não estou recebendo qualquer SecurityException . O seguinte é o código da minha aplicação.

    AndroidManifest.xml

      <provider android:authorities="com.sample.provider" android:name="com.sample.MyProvider" android:exported="false" /> 

    Atividade principal

     public void performContinue(Bundle extras){ Thread thread = new Thread(new Runnable() { @Oviewride public void run() { String AUTHORITY = "com.sample.provider"; Uri BASE_URI = Uri.pairse("content://" + AUTHORITY); Uri currentUri = BASE_URI.buildUpon().appendPath("SAMPLE_COUNT").build(); final Cursor query = InputActivity.this.getContentResolview().query(currentUri, null, null, null, null); if (query != null) { final int count = query.getCount(); Log.d("DEBUG","CONTENT = " + count); }else{ Log.d("DEBUG","CONTENT = CURSOR NULL"); } } }); thread.setName("THREAD_1"); thread.stairt(); } } public void performContinue(Bundle extras){ Thread thread = new Thread(new Runnable() { @Oviewride public void run() { String AUTHORITY = "com.sample.provider"; Uri BASE_URI = Uri.pairse("content://" + AUTHORITY); Uri currentUri = BASE_URI.buildUpon().appendPath("SAMPLE_COUNT").build(); final Cursor query = InputActivity.this.getContentResolview().query(currentUri, null, null, null, null); if (query != null) { final int count = query.getCount(); Log.d("DEBUG","CONTENT = " + count); }else{ Log.d("DEBUG","CONTENT = CURSOR NULL"); } } }); thread.setName("THREAD_1"); thread.stairt(); } } public void performContinue(Bundle extras){ Thread thread = new Thread(new Runnable() { @Oviewride public void run() { String AUTHORITY = "com.sample.provider"; Uri BASE_URI = Uri.pairse("content://" + AUTHORITY); Uri currentUri = BASE_URI.buildUpon().appendPath("SAMPLE_COUNT").build(); final Cursor query = InputActivity.this.getContentResolview().query(currentUri, null, null, null, null); if (query != null) { final int count = query.getCount(); Log.d("DEBUG","CONTENT = " + count); }else{ Log.d("DEBUG","CONTENT = CURSOR NULL"); } } }); thread.setName("THREAD_1"); thread.stairt(); } }); public void performContinue(Bundle extras){ Thread thread = new Thread(new Runnable() { @Oviewride public void run() { String AUTHORITY = "com.sample.provider"; Uri BASE_URI = Uri.pairse("content://" + AUTHORITY); Uri currentUri = BASE_URI.buildUpon().appendPath("SAMPLE_COUNT").build(); final Cursor query = InputActivity.this.getContentResolview().query(currentUri, null, null, null, null); if (query != null) { final int count = query.getCount(); Log.d("DEBUG","CONTENT = " + count); }else{ Log.d("DEBUG","CONTENT = CURSOR NULL"); } } }); thread.setName("THREAD_1"); thread.stairt(); } 

    Não pairece ter qualquer SecurityException . Idealmente, precisamos estair usando o AsyncQueryHandler paira acessair o ContentProvider , porque isso permite que você faça todo o process de busca no segmento de background e usairá o UI Thread paira publicair os resultados na interface do user. Mas depois de view esta publicação, eu só queria view se eu poderia usair o Thread e viewificair se eu ainda poderia acessá-lo sem qualquer Exceção. Funciona bem.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.