Переглянути джерело

Fix android.os.FileUriExposedException with Android 7 or newer

Sebastián Katzer 8 роки тому
батько
коміт
3b97aa4a48

+ 18 - 0
plugin.xml

@@ -104,6 +104,16 @@
         </config-file>
 
         <config-file target="AndroidManifest.xml" parent="/manifest/application">
+            <provider
+                android:name="de.appplant.cordova.plugin.notification.util.AssetProvider"
+                android:authorities="${applicationId}.provider"
+                android:exported="false"
+                android:grantUriPermissions="true" >
+                <meta-data
+                    android:name="android.support.FILE_PROVIDER_PATHS"
+                    android:resource="@xml/localnotification_provider_paths"/>
+            </provider>
+
             <receiver
                 android:name="de.appplant.cordova.plugin.localnotification.TriggerReceiver"
                 android:exported="false" />
@@ -131,6 +141,10 @@
             <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
         </config-file>
 
+        <source-file
+            src="src/android/xml/localnotification_provider_paths.xml"
+            target-dir="res/xml" />
+
         <source-file
             src="src/android/LocalNotification.java"
             target-dir="src/de/appplant/cordova/plugin/localnotification" />
@@ -191,6 +205,10 @@
             src="src/android/notification/trigger/MatchTrigger.java"
             target-dir="src/de/appplant/cordova/plugin/notification/trigger" />
 
+        <source-file
+            src="src/android/notification/util/AssetProvider.java"
+            target-dir="src/de/appplant/cordova/plugin/notification/util" />
+
         <source-file
             src="src/android/notification/util/AssetUtil.java"
             target-dir="src/de/appplant/cordova/plugin/notification/util" />

+ 11 - 2
src/android/notification/Builder.java

@@ -25,6 +25,8 @@ import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.NotificationCompat.MessagingStyle.Message;
 
@@ -88,15 +90,22 @@ public final class Builder {
      * @return The final notification to display.
      */
     public Notification build() {
-        int smallIcon = options.getSmallIcon();
         NotificationCompat.Builder builder;
 
         if (options.isSilent()) {
             return new Notification(context, options);
         }
 
+        int smallIcon = options.getSmallIcon();
+        Uri sound     = options.getSound();
+        Bundle extras = new Bundle();
+
+        extras.putString(Options.EXTRA, options.toString());
+        extras.putString(Options.SOUND_EXTRA, sound.toString());
+
         builder = new NotificationCompat.Builder(context, Manager.CHANNEL_ID)
                 .setDefaults(options.getDefaults())
+                .setExtras(extras)
                 .setChannelId(options.getChannel())
                 .setContentTitle(options.getTitle())
                 .setContentText(options.getText())
@@ -105,7 +114,7 @@ public final class Builder {
                 .setAutoCancel(options.isAutoClear())
                 .setOngoing(options.isSticky())
                 .setColor(options.getColor())
-                .setSound(options.getSound())
+                .setSound(sound)
                 .setVisibility(options.getVisibility())
                 .setPriority(options.getPriority())
                 .setShowWhen(options.getShowWhen())

+ 10 - 10
src/android/notification/Notification.java

@@ -29,6 +29,7 @@ import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.net.Uri;
 import android.os.Build;
 import android.support.v4.app.NotificationCompat;
 
@@ -189,17 +190,16 @@ public final class Notification {
      * Present the local notification to user.
      */
     public void show () {
-        // TODO Show dialog when in foreground
-        showNotification();
-    }
+        if (builder == null)
+            return;
 
-    /**
-     * Show as local notification when in background.
-     */
-    private void showNotification () {
-        if (builder != null) {
-            getNotMgr().notify(getId(), builder.build());
-        }
+        String sound = builder.getExtras().getString(Options.SOUND_EXTRA);
+        Uri soundUri = Uri.parse(sound);
+
+        context.grantUriPermission("com.android.systemui", soundUri,
+                Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+        getNotMgr().notify(getId(), builder.build());
     }
 
     // /**

+ 3 - 0
src/android/notification/Options.java

@@ -56,6 +56,9 @@ public final class Options {
     // Key name for bundled extras
     public static final String EXTRA = "NOTIFICATION_OPTIONS";
 
+    // Key name for bundled sound extra
+    public static final String SOUND_EXTRA = "NOTIFICATION_SOUND";
+
     // Default icon path
     private static final String DEFAULT_ICON = "res://icon";
 

+ 26 - 0
src/android/notification/util/AssetProvider.java

@@ -0,0 +1,26 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package de.appplant.cordova.plugin.notification.util;
+
+import android.support.v4.content.FileProvider;
+
+public class AssetProvider extends FileProvider {
+    // Nothing to do here
+}

+ 15 - 3
src/android/notification/util/AssetUtil.java

@@ -112,7 +112,7 @@ public final class AssetUtil {
             return Uri.EMPTY;
         }
 
-        return Uri.fromFile(file);
+        return getUriFromFile(file);
     }
 
     /**
@@ -142,7 +142,7 @@ public final class AssetUtil {
             outStream.flush();
             outStream.close();
 
-            return Uri.fromFile(file);
+            return getUriFromFile(file);
 
         } catch (Exception e) {
             Log.e("Asset", "File not found: assets/" + resPath);
@@ -213,7 +213,7 @@ public final class AssetUtil {
             outStream.flush();
             outStream.close();
 
-            return Uri.fromFile(file);
+            return getUriFromFile(file);
 
         } catch (MalformedURLException e) {
             Log.e("Asset", "Incorrect URL");
@@ -346,6 +346,18 @@ public final class AssetUtil {
         return new File(storage, name);
     }
 
+    /**
+     * Get content URI for the specified file.
+     *
+     * @param file The file to get the URI.
+     *
+     * @return content://...
+     */
+    private Uri getUriFromFile(File file) {
+        String authority = context.getPackageName() + ".provider";
+        return AssetProvider.getUriForFile(context, authority, file);
+    }
+
     /**
      * Package name specified by the resource bundle.
      */

+ 24 - 0
src/android/xml/localnotification_provider_paths.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+    <external-path name="external_files" path="."/>
+</paths>