2

Androidアプリでスクリーンショットを検出しようとしています。 私はここで Android | contentObserver |コンテンツURIにリソースIDが含まれていません

M.

Android上でそれをFileObserverための known issueを使用していない、メディアディレクトリの変化を検出するcontentObserverを使用していますが、コードスニペットです:

handlerThread = new HandlerThread("content_observer"); 
    handlerThread.start(); 
    final Handler handler = new Handler(handlerThread.getLooper()) { 
     @Override 
     public void handleMessage(Message msg) { 
      super.handleMessage(msg); 
     } 
    }; 

    getContentResolver().registerContentObserver(
      MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
      true, 
      new ContentObserver(handler) { 
       @Override 
       public void onChange(boolean selfChange, Uri uri) { 
        Log.d(TAG, "URL : " + uri.toString()); 

        //Code to query using content resolver 
        if (uri.toString().matches(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString())) { 

         Cursor cursor = null; 
         try { 
          cursor = getContentResolver().query(uri, new String[] { 
            MediaStore.Images.Media.DISPLAY_NAME, 
            MediaStore.Images.Media.DATA 
          }, null, null, null); 
          if (cursor != null && cursor.moveToFirst()) {   
          //Logic to filter if it is a screenshot file 
          } 
         } finally { 
          if (cursor != null) { 
           cursor.close(); 
          } 
         } 
        } 
        super.onChange(selfChange, uri); 
       } 
      } 
    ); 

のonChangeは、スクリーンショットの後に(呼び出された場合/ media/external/images/media "というURIは、リソースIDを含むURI全体ではなく、content:// media/external/images/media です。外部/画像/メディア/ 12345、これは私が試したデバイスのほとんどに発生します - Moto G3(Androi d 6.0.1)、Nexus 5(Android 6.0)のように、サムスンS5のURI(IDを含む)全体が6.0.1で動作します。

これは既知の問題ですか?

IDを取得するにはどうすればよいですか?

メディアディレクトリ全体を繰り返し処理し、アプリがアクティブなときにスクリーンショットが取得されたかどうかを確認するのではなく、コンテンツURIのリソースIDを取得すると、ファイルの(例えば、バックグラウンドで起こっているWhatsAppイメージのダウンロードも監視しています)。

答えて

2

MediaStoreで指定されたテーブルに挿入すると、正しくUriを受け取ることができなくなると思います。このライン

@Override 
public Uri insert(Uri uri, ContentValues initialValues) { 
    int match = URI_MATCHER.match(uri); 

    ArrayList<Long> notifyRowIds = new ArrayList<Long>(); 
    Uri newUri = insertInternal(uri, match, initialValues, notifyRowIds); 
    notifyMtp(notifyRowIds); 

    // do not signal notification for MTP objects. 
    // we will signal instead after file transfer is successful. 
    if (newUri != null && match != MTP_OBJECTS) { 
     getContext().getContentResolver().notifyChange(uri, null); 
    } 
    return newUri; 
} 

注:getContext().getContentResolver().notifyChange(uri, null)

これは(hereから採取)のAndroid 5.1.1用MediaProvider#insert()方法の源です。

上記は、MediaProviderに挿入すると、通知がUri(常にディレクトリ "Uri")に指定されて送信されることを意味します。これはおそらくバグです。uriの代わりにnewUriを使用すると、正しく動作することが期待されます。

SamsungがMarshmallowで動作する場合、これはAndroid 6以降で修正されたか、またはSamsungがAOSPのビルドで修正しました。しかし、私はあなたが本当にこれを信じて信頼できると確信できるとは思いません。

関連する問題